/**
   @file sys_usw_acl.c

   @date 2015-11-01

   @version v3.0

 */

/****************************************************************************
*
* Header Files
*
****************************************************************************/
#include "ctc_error.h"
#include "ctc_const.h"
#include "ctc_common.h"
#include "ctc_macro.h"
#include "ctc_debug.h"
#include "ctc_hash.h"
#include "ctc_parser.h"
#include "ctc_acl.h"
#include "ctc_linklist.h"
#include "ctc_spool.h"
#include "ctc_field.h"
#include "ctc_packet.h"

#include "sys_usw_common.h"
#include "sys_usw_opf.h"
#include "sys_usw_chip.h"
#include "sys_usw_parser.h"
#include "sys_usw_parser_io.h"
#include "sys_usw_ftm.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_register.h"
#include "sys_usw_port.h"
#include "sys_usw_acl.h"


#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "sys_usw_dma.h"

#define SYS_USW_ACL_MATCH_GRP_MAX_COUNT    255
#define SYS_USW_ACL_MAX_KEY_SIZE  40
#define SYS_NH_INTERNAL_NHID_BASE 0x80000000

#define SYS_ACL_SHOW_SUB_STR(color, index, data, string, is_str, valid)  \
    if (valid){\
        if (is_str){\
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " %-2s", color[index]);\
        } else {\
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " %u(%s)", data, color[index]);\
        }\
    }\
    index++;

#define SYS_ACL_SHOW_CP_TO_CPU_REASON(copy_to_cpu, color, index, valid)  \
    if (valid){\
        if (CTC_ACL_TO_CPU_MODE_TO_CPU_NOT_COVER == copy_to_cpu.mode){\
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n  %-16s  %s: %s", "", color[index], _sys_usw_get_cp_to_cpu_desc(copy_to_cpu.mode));\
        } else if (CTC_ACL_TO_CPU_MODE_TO_CPU_COVER == copy_to_cpu.mode){\
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n  %-16s  %s: %s, %s:%u", "", color[index], _sys_usw_get_cp_to_cpu_desc(copy_to_cpu.mode),"ReasonID",copy_to_cpu.cpu_reason_id );\
        } else if (CTC_ACL_TO_CPU_MODE_CANCEL_TO_CPU == copy_to_cpu.mode){\
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n  %-16s  %s: %s", "", color[index], _sys_usw_get_cp_to_cpu_desc(copy_to_cpu.mode));\
        }\
    }\
    index++;

/*
#define SYS_ACL_SHOW_AD_WITH_COLOR(lchip, entry_id, field_action, field_str, color, sub_str_dump)  do{\
        color = CTC_QOS_COLOR_NONE;\
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action))\
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s:", field_str);\
        CTC_BIT_SET(color, CTC_QOS_COLOR_GREEN);\
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action))\
            sub_str_dump;\
        color = 0;\
        CTC_BIT_SET(color, CTC_QOS_COLOR_YELLOW);\
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action))\
            sub_str_dump;\
        color = 0;\
        CTC_BIT_SET(color, CTC_QOS_COLOR_RED);\
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action))\
            sub_str_dump;\
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");\
    }while(0)
*/
#define SYS_ACL_SHOW_AD_WITH_COLOR(lchip, entry_id, field_action, field_str, color, sub_str_dump)  do{\
        uint8 __valid = 0; \
        color = CTC_QOS_COLOR_NONE; \
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action)){ \
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s:", field_str); \
            __valid = 1; }\
        color = CTC_QOS_COLOR_GREEN;\
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action)) \
            sub_str_dump;\
        color = CTC_QOS_COLOR_YELLOW;\
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action)) \
            sub_str_dump;\
        color = CTC_QOS_COLOR_RED;\
        if(!_sys_usw_acl_get_action_field(lchip, entry_id, &field_action)) \
            sub_str_dump;\
        if(__valid)\
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");\
    }while(0)


sys_acl_master_t* p_usw_acl_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};

int32
_sys_tmm_acl_get_key_field( uint8 lchip, uint32 qid,sys_acl_entry_t* pe, uint32* key_width, uint32* value_array,
                            uint32* mask_array, uint16* offset_dst);

enum sys_acl_udf_union_chk_e
{
    SYS_ACL_UDF_UNION_CHK_NONE,
    SYS_ACL_UDF_UNION_CHK_ETH,
    SYS_ACL_UDF_UNION_CHK_IP,
    SYS_ACL_UDF_UNION_CHK_MPLS,
    SYS_ACL_UDF_UNION_CHK_GRE,
    SYS_ACL_UDF_UNION_CHK_TCP_UDP,
    MAX_SYS_ACL_UDF_UNION_CHK
};
typedef enum sys_acl_udf_union_chk_e sys_acl_udf_union_chk_t;

#define SYS_ACL_UDF_UNION_CHECK(lchip, value1, value2, type) \
{\
    switch(type)\
    {\
        case SYS_ACL_UDF_UNION_CHK_ETH:\
            if((!value1) || (CTC_PARSER_L3_TYPE_IP == value2) || (CTC_PARSER_L3_TYPE_IPV4 == value2) || (CTC_PARSER_L3_TYPE_IPV6 == value2) \
                || (CTC_PARSER_L3_TYPE_MPLS == value2) || (CTC_PARSER_L3_TYPE_MPLS_MCAST == value2))\
            {\
                return CTC_E_INVALID_PARAM;\
            }\
            break;\
        case SYS_ACL_UDF_UNION_CHK_IP:\
            if ((!value1) || (!((CTC_PARSER_L3_TYPE_IP == value2) || (CTC_PARSER_L3_TYPE_IPV4 == value2) || (CTC_PARSER_L3_TYPE_IPV6 == value2)))) \
            {\
                return CTC_E_INVALID_PARAM;\
            }\
            break;\
        case SYS_ACL_UDF_UNION_CHK_MPLS:\
            if ((!value1) || (!((CTC_PARSER_L3_TYPE_MPLS == value2) || (CTC_PARSER_L3_TYPE_MPLS_MCAST == value2)))) \
            {\
                return CTC_E_INVALID_PARAM;\
            }\
            break;\
        case SYS_ACL_UDF_UNION_CHK_GRE:\
            if ((!value1) || (CTC_PARSER_L4_TYPE_GRE != sys_usw_l4_type_map(lchip, value2, FALSE))) \
            {\
                return CTC_E_INVALID_PARAM;\
            }\
            break;\
        case SYS_ACL_UDF_UNION_CHK_TCP_UDP:\
            if ((!value1) || (!((CTC_PARSER_L4_TYPE_TCP == value2) || (CTC_PARSER_L4_TYPE_UDP == sys_usw_l4_type_map(lchip, value2, FALSE))))) \
            {\
                return CTC_E_INVALID_PARAM;\
            }\
            break;\
    }\
}

#define SYS_ACL_SET_FLAG(VAL, FLAG, IS_ADD)\
if(IS_ADD){\
    CTC_SET_FLAG(VAL, FLAG);}\
else{\
    CTC_UNSET_FLAG(VAL, FLAG);}

#define SYS_ACL_JUDGE_AD_TYPE(ad_type, condition,  value) \
    ad_type = ((condition) || (ad_type) == (value)) ? (value) : SYS_ACL_AD_TYPE_DISABLE;

extern int32
sys_usw_dma_copy_desc_data(uint8 lchip, uint8 chan_id, uint32 src_desc_idx, uint32 dst_desc_idx);
extern uint8
drv_ser_get_tcam_scan_enable(uint8 lchip);
extern int32
sys_usw_acl_fpa_block_init(uint8 lchip, uint8 block_id);

int32
_sys_tmm_acl_build_extract_db(uint8 lchip, uint8 size_mode, sys_acl_flex_key_t *fk);
int32
_sys_tmm_acl_map_key_type_to_ltid(uint8 key_type, uint8 *p_ltid);


int32
sys_usw_acl_alloc_offset(uint8 lchip,
                         sys_acl_block_t * pb,
                         sys_acl_entry_t* pe,
                         uint8 key_size)
{
    int32 ret = 0;
    uint8 part = 0;
    uint32 block_index = 0;

    if(SYS_USW_ACL_UPA_EN(lchip, pe->group->group_info.dir))
    {
        CTC_ERROR_RETURN(pb->fpab.free_count < 1? CTC_E_NO_RESOURCE: CTC_E_NONE);
        SYS_ACL_PART_LOOP(part, pb->fpab.part_num)
        {
            if (part < key_size)
            {
                pb[part].fpab.free_count--;
                pb[part].fpab.sub_free_count[key_size]--;
            }
        }
        block_index = pe->fpae.priority;
    }
    else
    {
        CTC_ERROR_RETURN(fpa_usw_alloc_offset(p_usw_acl_master[lchip]->fpa, &pb->fpab, key_size, pe->fpae.priority, &block_index));
    }


   if (key_size == CTC_FPA_KEY_SIZE_160 && pb->fpab.vblock)
   {
       int32 local_block_idx = 0;
       ctc_fpa_block_t* pb_part = NULL;

       pb->fpab.vblock->entries[block_index] = &pe->fpae;
       SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "add vblock:%d, index:%d, entry:%d\n", pb->block_id, block_index, pe->fpae.entry_id);

       pb_part = fpa_get_local_info_by_fpa_idx(&pb->fpab, block_index, &local_block_idx);
       pb_part->entries[local_block_idx] = &pe->fpae;
       SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "add block:%d, index:%d, entry:%d\n", pb->block_id + pb_part->part, local_block_idx, pe->fpae.entry_id);

       /*pe index*/
       block_index = fpa_get_index_by_fpa_idx(&pb->fpab, block_index);
   }
   else
   {
       for (part = 0; part < key_size; part++)
       {
           (pb + part)->fpab.entries[block_index] = &pe->fpae;
           SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "add block:%d, index:%d, entry:%d\n", pb->block_id + part, block_index, pe->fpae.entry_id);
       }
   }

    /* set block index */
    pe->fpae.offset_a = block_index;
    pe->fpae.step     = 1;
    pe->fpae.real_step= 1;
    pe->fpae.key_size = key_size;
    return ret;

}



#define __ACL_GET_INFO__

int32
_sys_usw_acl_get_key_size_bitmap(uint8 lchip, sys_acl_block_t* pb, uint8* p_key_used_bmp, uint8 dir)
{
    uint8   index               = 0;
    uint8   key_used_bmp        = 0;
    uint16  sub_entry_used      = 0;
    uint16  short_entry_used    = 0;

    CTC_PTR_VALID_CHECK(pb);

    if (SYS_USW_ACL_UPA_EN(lchip, dir))     /*first check key size 80 used or not, then check key size 160 used or not*/
    {
        index = CTC_FPA_KEY_SIZE_80;
        short_entry_used = pb->fpab.sub_entry_count[index] - pb->fpab.sub_free_count[index];
        short_entry_used? CTC_BIT_SET(key_used_bmp, index): CTC_BIT_UNSET(key_used_bmp, index);
        index = CTC_FPA_KEY_SIZE_160;
        sub_entry_used = !key_used_bmp? pb->fpab.entry_count - pb->fpab.free_count: 0;
        sub_entry_used? CTC_BIT_SET(key_used_bmp, index): CTC_BIT_UNSET(key_used_bmp, index);
    }
    else
    {
        for (index=CTC_FPA_KEY_SIZE_80; index<CTC_FPA_KEY_SIZE_NUM; index+=1)
        {
            sub_entry_used = pb->fpab.sub_entry_count[index] - pb->fpab.sub_free_count[index];
            sub_entry_used? CTC_BIT_SET(key_used_bmp, index): CTC_BIT_UNSET(key_used_bmp, index);
        }
    }

    if (p_key_used_bmp)
    {
        *p_key_used_bmp = key_used_bmp;
    }
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "  key_used_bitmap: 0x%X \n", key_used_bmp);
    return CTC_E_NONE;
}

/*
    fixed key, origin_key_type => fk->origin_key_type
    others,    origin_key_type => key_type
*/
uint8
sys_usw_acl_get_origin_key_type(uint8 lchip, sys_acl_entry_t* pe)
{
    sys_acl_fixed_key_t* fk = NULL;
    sys_acl_flex_hash_t* fk_hash = NULL;
    uint8 key_type = pe->key_type;
    if (!SYS_ACL_GROUP_IS_PRESEL(pe->group) && ACL_ENTRY_IS_TCAM(pe) && SYS_ACL_KEY_IS_FLEX(key_type))
    {
        fk = ctc_vector_get(p_usw_acl_master[lchip]->fixed_key_vec,key_type);
        key_type = fk ? fk->origin_key_type : key_type;
    }
    else if(SYS_ACL_KEY_IS_FLEX_HASH0(pe->action_type, pe->key_type, pe->group->group_info.block_id))
    {
         fk_hash = ctc_vector_get(p_usw_acl_master[lchip]->flex_key_vec,SYS_ACL_FLEX_KEY_IDX(CTC_INGRESS, key_type));
         key_type = fk_hash ? fk_hash->origin_key_type : key_type;
    }
    return key_type;
}

uint8
_sys_usw_acl_get_key_size(uint8 lchip, uint8 by_key_type, sys_acl_entry_t * pe, uint8* o_step)
{
    uint8 key_size = 0;
    uint8 step = 0;
    uint8 key_type = 0;
    sys_acl_flex_hash_t* p_fk_hash = NULL;

    if (SYS_ACL_GROUP_IS_PRESEL(pe->group) && ACL_ENTRY_IS_TCAM(pe))
    {
        key_size = pe->fpae.key_size;
        if (o_step)
        {
            *o_step = 1;
        }

        return key_size;
    }

    key_type = sys_usw_acl_get_origin_key_type(lchip, pe);

    switch (key_type)
    {
        case CTC_ACL_KEY_INTERFACE:
            key_size = CTC_FPA_KEY_SIZE_80;
            step = 1;
            break;

        case CTC_ACL_KEY_CID:
        case CTC_ACL_KEY_MAC:
        case CTC_ACL_KEY_IPV4:
            key_size = CTC_FPA_KEY_SIZE_160;
            step = 2;
            break;

        case CTC_ACL_KEY_IPV6:
        case CTC_ACL_KEY_MAC_IPV4:
        case CTC_ACL_KEY_IPV4_EXT:
        case CTC_ACL_KEY_FWD:
        case CTC_ACL_KEY_COPP:
        case CTC_ACL_KEY_UDF:
            key_size = CTC_FPA_KEY_SIZE_320;
            step = 4;
            break;

        case CTC_ACL_KEY_IPV6_EXT:
        case CTC_ACL_KEY_MAC_IPV6:
        case CTC_ACL_KEY_MAC_IPV4_EXT:
        case CTC_ACL_KEY_FWD_EXT:
        case CTC_ACL_KEY_COPP_EXT:
            key_size = CTC_FPA_KEY_SIZE_640;
            step = 8;
            break;
        case CTC_ACL_KEY_HASH_MAC:
        case CTC_ACL_KEY_HASH_IPV4:
        case CTC_ACL_KEY_HASH_MPLS:
        case CTC_ACL_KEY_HASH_NSH:
            key_size = CTC_FPA_KEY_SIZE_160;
            step = 1;
            break;

        case CTC_ACL_KEY_HASH_L2_L3:
        case CTC_ACL_KEY_HASH_IPV6:
            key_size = CTC_FPA_KEY_SIZE_320;
            step = 2;
            break;
        default:
            step = 1;
            break;
    }

    /* just for flex hash 0 */
    if(SYS_ACL_KEY_IS_FLEX_HASH0(pe->action_type, pe->key_type, pe->group->group_info.block_id))
    {
        p_fk_hash = ctc_vector_get(p_usw_acl_master[lchip]->flex_key_vec,SYS_ACL_FLEX_KEY_IDX(CTC_INGRESS, pe->key_type));
        if(p_fk_hash && (p_fk_hash->mode == CTC_FIELD_FLEX_KEY_MODE_DOUBLE_APPEND))
        {
            step = step << 1;
            key_size = key_size << 1;
        }
    }

    if(!by_key_type && ACL_ENTRY_IS_TCAM(pe) && (key_type != CTC_ACL_KEY_INTERFACE) && (pe->group->group_info.key_size > CTC_FPA_KEY_SIZE_80))
    {
        key_size = pe->group->group_info.key_size;
        step = 1 << key_size;
    }
    if(o_step)
    {
        *o_step = step;
    }

    return key_size;
}

int32
_sys_usw_acl_get_entry_by_eid(uint8 lchip, uint32 eid, sys_acl_entry_t** pe)
{
    sys_acl_entry_t sys_entry;

    CTC_PTR_VALID_CHECK(pe);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&sys_entry, 0, sizeof(sys_acl_entry_t));
    sys_entry.fpae.entry_id = eid;
    *pe = ctc_hash_lookup(p_usw_acl_master[lchip]->entry, &sys_entry);

    return CTC_E_NONE;
}

/*
 * get sys entry node by entry id
 * pg, pb if be NULL, won't care.
 * pe cannot be NULL.
 */
int32
_sys_usw_acl_get_nodes_by_eid(uint8 lchip, uint32 eid, sys_acl_entry_t** pe, sys_acl_group_t** pg, sys_acl_block_t** pb)
{
    sys_acl_entry_t sys_entry;
    sys_acl_entry_t * pe_lkup = NULL;
    sys_acl_group_t * pg_lkup = NULL;
    sys_acl_block_t * pb_lkup = NULL;
    uint8           block_id  = 0;

    CTC_PTR_VALID_CHECK(pe);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&sys_entry, 0, sizeof(sys_acl_entry_t));
    sys_entry.fpae.entry_id = eid;

    pe_lkup = ctc_hash_lookup(p_usw_acl_master[lchip]->entry, &sys_entry);

    if (pe_lkup)
    {
        pg_lkup = pe_lkup->group;
        SYS_ACL_CHECK_GROUP_UNEXIST(pg_lkup);

        /* get block */
        if (ACL_ENTRY_IS_TCAM(pe_lkup))
        {
            block_id = pg_lkup->group_info.block_id;
            if(CTC_EGRESS == pg_lkup->group_info.dir)
            {
                block_id += p_usw_acl_master[lchip]->igs_block_num;
            }
            pb_lkup  = &SYS_ACL_BLOCK(lchip, block_id);
        }
    }

    *pe = pe_lkup;
    if (pg)
    {
        *pg = pg_lkup;
    }
    if (pb)
    {
        *pb = pb_lkup;
    }

    return CTC_E_NONE;
}

/*
 * get sys group node by group id
 */
int32
_sys_usw_acl_get_group_by_gid(uint8 lchip, uint32 gid, sys_acl_group_t** o_group)
{
    sys_acl_group_t * p_sys_group_lkup = NULL;
    sys_acl_group_t sys_group;

    CTC_PTR_VALID_CHECK(o_group);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&sys_group, 0, sizeof(sys_acl_group_t));
    sys_group.group_id = gid;

    p_sys_group_lkup = ctc_hash_lookup(p_usw_acl_master[lchip]->group, &sys_group);

    *o_group = p_sys_group_lkup;

    return CTC_E_NONE;
}

#define __ACL_FPA_CALLBACK__
int32
_sys_usw_acl_change_stats_ptr_cb(uint8 lchip, uint32 new_stats_ptr, uint8 new_ram, void* user_data)
{
    uint8   global_pp_en = 0;
    uint32 key_id;
    uint32 act_id;
    uint32 hw_index;
    uint32 cmd;
    DsAcl0Ingress_m dsacl;
    sys_acl_entry_t*    pe=  (sys_acl_entry_t*)user_data;

    if(pe->ua && !pe->ua_type)
    {
        if(DRV_FROM_TMM(lchip) && CTC_EGRESS == pe->group->group_info.dir)
        {
            SetDsEpeAcl(V, statsPtr_f, &pe->ua->buffer.action, new_stats_ptr);    /* tmm egs */
            SetDsEpeAcl(V, statsPoolNumber_f, &pe->ua->buffer.action, new_ram);   /* tmm egs */
        }
        else
        {
            SetDsAcl(V, u2_gStatsOp_statsPtr_f, &pe->ua->buffer.action, new_stats_ptr);
            SetDsAcl(V, u2_gStatsOp_statsPoolNumber_f, &pe->ua->buffer.action, new_ram);
            SetDsAcl(V, u2_gStatsOp_aclStatsIsPrivate_f, &pe->ua->buffer.action, SYS_STATS_IS_ACL_PRIVATE(new_stats_ptr) ? 1 : 0); /* TM */
        }
        return CTC_E_NONE;
    }
    SYS_ACL_GET_TBL_FUNC(lchip, pe, &key_id, &act_id, &hw_index);
    hw_index = SYS_ACL_MAP_DRV_AD_INDEX(hw_index, pe->fpae.real_step);

    cmd = DRV_IOR(act_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, hw_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &dsacl);
    if(DRV_FROM_TMM(lchip) && CTC_EGRESS == pe->group->group_info.dir)
    {
        SetDsEpeAcl(V, statsPtr_f, &dsacl, new_stats_ptr);    /* tmm egs */
        SetDsEpeAcl(V, statsPoolNumber_f, &dsacl, new_ram);   /* tmm egs */
    }
    else
    {
        SetDsAcl(V, u2_gStatsOp_statsPtr_f, &dsacl, new_stats_ptr);
        SetDsAcl(V, u2_gStatsOp_statsPoolNumber_f, &dsacl, new_ram);
        SetDsAcl(V, u2_gStatsOp_aclStatsIsPrivate_f, &dsacl, SYS_STATS_IS_ACL_PRIVATE(new_stats_ptr) ? 1 : 0);
    }
    global_pp_en = SYS_ACL_IS_GLOBAL_PP_EN_LKUP(lchip, pe->group->group_info.dir, pe->group->group_info.block_id);
    cmd = DRV_IOW(act_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, hw_index, DRV_CMD_BMP_EN(cmd, (MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)) && !global_pp_en), &dsacl));
    return CTC_E_NONE;
}


int32
_sys_usw_acl_get_block_by_pe_fpa(uint8 lchip, ctc_fpa_entry_t* pe, ctc_fpa_block_t** pb)
{
    uint8          block_id;
    sys_acl_entry_t* entry;

    *pb = NULL;
    entry = ACL_OUTER_ENTRY(pe);

    block_id = entry->group->group_info.block_id;
    if(CTC_EGRESS == entry->group->group_info.dir)
    {
        block_id += p_usw_acl_master[lchip]->igs_block_num;
    }

#if 0
    if (SYS_ACL_GROUP_IS_PRESEL(entry->group))
    {
        uint32 _hw_index = 0;
        sys_usw_acl_get_block_id_and_index(lchip, entry, &block_id, &_hw_index);
    }
#endif

    *pb = &(SYS_ACL_BLOCK(lchip, block_id).fpab);

    return CTC_E_NONE;
}

/*
 * move entry in hardware table to an new index.
 */
int32
_sys_usw_acl_entry_move_hw_fpa(uint8 lchip, ctc_fpa_entry_t* p_fpa_entry, int32 tcam_idx_new)
{
    uint32  old_key_id  = 0;
    uint32  old_act_id  = 0;
    uint32  new_key_id  = 0;
    uint32  new_act_id  = 0;
    uint32  old_hw_index = 0;
    uint32  new_hw_index = 0;
    uint32  old_offset_a = 0;
    uint32  temp_id      = 0;
    sys_acl_entry_t*  pe_lkup  = NULL;
    uint8 part_num = 1;
    sys_stats_acl_change_t stats_change = {0};
    uint8 global_pp_en  = 0;
    uint8 pp_id = lchip - SYS_PP_BASE(lchip);
    drv_ioctl_param_t src_ioctl_param;
    drv_ioctl_param_t dst_ioctl_param;

    CTC_PTR_VALID_CHECK(p_fpa_entry);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    pe_lkup = _ctc_container_of(p_fpa_entry, sys_acl_entry_t, fpae);

    old_offset_a = p_fpa_entry->offset_a;
    if (SYS_ACL_GROUP_IS_PRESEL(pe_lkup->group))
    {
        SYS_ACL_GET_STATS_ID(temp_id, pe_lkup);

        SYS_ACL_KEY_SIZE_TO_PART_NUM(pe_lkup->fpae.key_size, part_num);

        if(0 != temp_id)
        {
            sys_acl_block_t* pb_tmp;
            uint8 block_base = (CTC_INGRESS==pe_lkup->group->group_info.dir) ? 0 : ACL_IGS_BLOCK_MAX_NUM;
            stats_change.cb = _sys_usw_acl_change_stats_ptr_cb;
            stats_change.user_data = (void*)pe_lkup;
            p_fpa_entry->offset_a = tcam_idx_new;

            pb_tmp = &SYS_ACL_BLOCK(lchip, pe_lkup->group->group_info.block_id+block_base);
            ACL_MAP_FLOW_STATS_BLOCK_ID(pe_lkup, pb_tmp, stats_change.new_block_id,pe_lkup->fpae.key_size);
            p_fpa_entry->offset_a = old_offset_a;
            stats_change.stats_id = temp_id;
            sys_usw_flow_stats_change_acl_statsptr(lchip, &stats_change);
        }
    }

    if (p_fpa_entry->flag != FPA_ENTRY_FLAG_INSTALLED)
    {
        return CTC_E_NONE;
    }

    SYS_ACL_GET_TBL_FUNC(lchip, pe_lkup, &old_key_id, &old_act_id, &old_hw_index);

    p_fpa_entry->offset_a = tcam_idx_new;
    SYS_ACL_GET_TBL_FUNC(lchip, pe_lkup, &new_key_id, &new_act_id, &new_hw_index);
    p_fpa_entry->offset_a = old_offset_a;

    global_pp_en = SYS_ACL_IS_GLOBAL_PP_EN_LKUP(SYS_PP_BASE(lchip), pe_lkup->group->group_info.dir, pe_lkup->group->group_info.block_id);

    /* move key and ad */
    src_ioctl_param.entry_len = part_num;
    src_ioctl_param.index = (DRV_IS_TMM(lchip) && CTC_EGRESS == pe_lkup->group->group_info.dir) ?old_hw_index/2 : old_hw_index;
    src_ioctl_param.op_bmp = (MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL) && !global_pp_en) ? (((1<<(pp_id/PP_NUM_PER_CORE)) << 6) | ((1<<(pp_id%PP_NUM_PER_CORE)) << 2)) : 0xfc;
    src_ioctl_param.p_value = NULL;
    src_ioctl_param.tbl_id = old_key_id;
    src_ioctl_param.ad_index = SYS_ACL_MAP_DRV_AD_INDEX(old_hw_index, pe_lkup->fpae.real_step);
    src_ioctl_param.ad_tbl_id = old_act_id;

    dst_ioctl_param.entry_len = part_num;
    dst_ioctl_param.index = (DRV_IS_TMM(lchip) && CTC_EGRESS == pe_lkup->group->group_info.dir) ?new_hw_index/2 : new_hw_index;
    dst_ioctl_param.op_bmp = (MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL) && !global_pp_en) ? (((1<<(pp_id/PP_NUM_PER_CORE)) << 6) | ((1<<(pp_id%PP_NUM_PER_CORE)) << 2)) : 0xfc;
    dst_ioctl_param.p_value = NULL;
    dst_ioctl_param.tbl_id = new_key_id;
    dst_ioctl_param.ad_index = SYS_ACL_MAP_DRV_AD_INDEX(new_hw_index, pe_lkup->fpae.real_step);
    dst_ioctl_param.ad_tbl_id = new_act_id;

    CTC_ERROR_RETURN(drv_ioctl_move_tcam(lchip,&src_ioctl_param, &dst_ioctl_param));
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_TCAM_ENTRY, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_BLOCK, 1);
    return CTC_E_NONE;
}
int32
_sys_usw_acl_udf_get_block_by_pe_fpa(uint8 lchip, ctc_fpa_entry_t* pe, ctc_fpa_block_t** pb)
{
    *pb = &p_usw_acl_master[lchip]->udf_block.fpab;
    return CTC_E_NONE;
}

int32
_sys_usw_acl_udf_move_hw_fpa(uint8 lchip, ctc_fpa_entry_t* p_fpa_entry, int32 tcam_idx_new)
{
    ParserUdfCamResult_m result[3];
    tbl_entry_t   tcam_key;
    ParserUdfCam_m buffer[2];
    uint32 cmd;
    sys_acl_udf_entry_t* p_udf = _ctc_container_of(p_fpa_entry, sys_acl_udf_entry_t, fpae);

    p_udf->key_index = tcam_idx_new;
    sys_usw_parser_io_get_parser_udf_cam_result(lchip, result, p_fpa_entry->offset_a, 0, p_usw_acl_master[lchip]->udf_mode);
    sys_usw_parser_io_set_parser_udf_cam_result(lchip, result, tcam_idx_new, 0, p_usw_acl_master[lchip]->udf_mode);

    if(0 == p_udf->is_installed)
    {
        return CTC_E_NONE;
    }
    tcam_key.data_entry = (uint32*)&buffer[0];
    tcam_key.mask_entry = (uint32*)&buffer[1];
    sys_usw_parser_io_get_parser_udf_cam(lchip, &tcam_key, p_fpa_entry->offset_a);
    sys_usw_parser_io_set_parser_udf_cam(lchip, &tcam_key, tcam_idx_new);

    cmd = DRV_IOD(ParserUdfCam_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, p_fpa_entry->offset_a, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key);
    return CTC_E_NONE;
}

#define __ACL_RANGE_MANAGE__

STATIC uint8
_sys_usw_acl_mapping_prg_range_type(uint8 in_type, uint8 is_sudf, uint8 sys_to_drv)
{
    /* ref  (cfgFieldType(2,0) == CBit(3, 'd', "0", 1)) ? tempSvid(15,0) :
            (cfgFieldType(2,0) == CBit(3, 'd', "1", 1)) ? tempCvid(15,0) :
            (cfgFieldType(2,0) == CBit(3, 'd', "2", 1)) ? tempIpTotalLen(15,0) :
            (cfgFieldType(2,0) == CBit(3, 'd', "3", 1)) ? tempL4SrcPort(15,0) :
            (cfgFieldType(2,0) == CBit(3, 'd', "4", 1)) ? tempL4DstPort(15,0) :
            (cfgFieldType(2,0) == CBit(3, 'd', "5", 1)) ? tempUdf(15,0) :
            (cfgFieldType(2,0) == CBit(3, 'd', "6", 1)) ? tempPktSvid(15,0) :
            (cfgFieldType(2,0) == CBit(3, 'd', "7", 1)) ? tempPktCvid(15,0) : CBit(16, 'd', "0", 1); */

    uint8 range_type_map[2][ACL_RANGE_TYPE_NUM] = {
                                {ACL_RANGE_TYPE_SVLAN,
                                 ACL_RANGE_TYPE_CVLAN,
                                 ACL_RANGE_TYPE_PKT_LENGTH,
                                 ACL_RANGE_TYPE_L4_SRC_PORT,
                                 ACL_RANGE_TYPE_L4_DST_PORT,
                                 is_sudf ? ACL_RANGE_TYPE_SUDF : ACL_RANGE_TYPE_UDF,
                                 ACL_RANGE_TYPE_NONE},
                                 {0, 2, 3, 4, 0, 1, 5, 5}};

    return range_type_map[sys_to_drv][in_type];
}

/**
 @brief set parser range op ctl
*/
int32
sys_usw_acl_set_range_op_ctl(uint8 lchip, uint8 range_id, sys_parser_range_op_ctl_t* p_range_ctl)
{
    uint32 cmd  = 0;
    uint8  step = 0;
	uint8 type = 0;
    ProgramAclRangeOpCtl_m range_ctl;
    uint32 range_ctl_table[CTC_BOTH_DIRECTION] = {ProgramAclRangeOpCtl_t, EgrProgramAclRangeOpCtl_t};

    CTC_PTR_VALID_CHECK(p_range_ctl);
    SYS_PARSER_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PARSER_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "range id:%d\n", range_id);
    SYS_PARSER_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "type:%d, min: %u, max: %u\n",
                                p_range_ctl->type, p_range_ctl->min_value, p_range_ctl->max_value);
    sal_memset(&range_ctl, 0, sizeof(range_ctl));

    type = _sys_usw_acl_mapping_prg_range_type(p_range_ctl->type, p_range_ctl->is_sudf, 1);

    cmd = DRV_IOR(range_ctl_table[p_range_ctl->dir], DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &range_ctl));
    step = ProgramAclRangeOpCtl_gRangeCheckCtl_1_valid_f - ProgramAclRangeOpCtl_gRangeCheckCtl_0_valid_f;

    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_valid_f + step*range_id, &range_ctl, (p_range_ctl->type != ACL_RANGE_TYPE_NONE)? 1 : 0);
    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_fieldType_f + step*range_id, &range_ctl, type);
    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_maxValue_f + step*range_id, &range_ctl, p_range_ctl->max_value);
    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_minValue_f + step*range_id, &range_ctl, p_range_ctl->min_value);

    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfDataShift_f + step*range_id, &range_ctl, p_range_ctl->udf_sel);
    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfIndex_f + step*range_id, &range_ctl, p_range_ctl->udf_index);
    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfMask_f + step*range_id, &range_ctl, p_range_ctl->udf_mask);
    SetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfDataSelect_f + step*range_id, &range_ctl, p_range_ctl->is_sudf ? 0: 1);

    cmd = DRV_IOW(range_ctl_table[p_range_ctl->dir], DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &range_ctl));

    return CTC_E_NONE;
}

int32
_sys_usw_acl_lookup_range(uint8 lchip, sys_acl_field_range_t* p_range, sys_parser_range_op_ctl_t *p_range_ctl, uint8* o_first_valid)
{
    uint8 index = 0;
    uint8 first_valid = 0;
    uint8 hit = 0;

    for(index = 0; index < p_range->entry_num; index++)
    {
        if((ACL_RANGE_TYPE_NONE == p_range->range[index].range_type) && (!hit))
        {
            first_valid = index;
            hit = 1;
        }
        if( (p_range_ctl->type == p_range->range[index].range_type)
            && (p_range_ctl->max_value == p_range->range[index].max)
            && (p_range_ctl->min_value == p_range->range[index].min)
            && (p_range_ctl->udf_index == p_range->range[index].udf_index)
            && (p_range_ctl->udf_sel == p_range->range[index].udf_sel)
            && (p_range_ctl->udf_mask == p_range->range[index].udf_mask)
            && (p_range_ctl->is_sudf == p_range->range[index].is_sudf))
        {
            break;
        }
    }

    if(o_first_valid)
    {
        *o_first_valid = first_valid;
    }

    return index;
}


int32
_sys_usw_acl_add_range_bitmap(uint8 lchip, sys_acl_field_range_t* p_range, sys_parser_range_op_ctl_t *p_range_ctl, uint8* o_range_id)
{
    uint8 index = 0;
    uint8 range_id = 0;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    index = _sys_usw_acl_lookup_range(lchip, p_range, p_range_ctl, &range_id);
    if(index < p_range->entry_num)
    {
        range_id = index;
        (p_range->range[index].ref)++;
    }
    else
    {
        if (0 == p_range->free_num)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No resource in ASIC \n");
            return CTC_E_NO_RESOURCE;

        }
        if ( CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
        {
            range_id = *o_range_id;
        }
        if (p_range->is_fg_rg)
        {
            CTC_ERROR_RETURN(sys_usw_acl_set_range_op_ctl(lchip, range_id, p_range_ctl));
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_parser_set_range_op_ctl(lchip, range_id, p_range_ctl));
        }

        p_range->range[range_id].range_type = p_range_ctl->type;
        p_range->range[range_id].min        = p_range_ctl->min_value;
        p_range->range[range_id].max        = p_range_ctl->max_value;
        p_range->range[range_id].ref        = 1;
        p_range->range[range_id].udf_index = p_range_ctl->udf_index;
        p_range->range[range_id].is_sudf   = p_range_ctl->is_sudf;
        p_range->range[range_id].udf_sel = p_range_ctl->udf_sel;
        p_range->range[range_id].udf_mask = p_range_ctl->udf_mask;


        (p_range->free_num)--;
    }
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO," range[%u].ref = %u\n", range_id, p_range->range[range_id].ref);
    if(o_range_id)
    {
        *o_range_id = range_id;
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"add field range, range-type: %d, range-id: %d, min: %u, max: %u\n",
                     p_range_ctl->type, range_id, p_range_ctl->min_value, p_range_ctl->max_value);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_remove_range_bitmap(uint8 lchip, sys_acl_field_range_t* p_range, uint8 range_id)
{
    sys_parser_range_op_ctl_t range_ctl = {0};

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);


    if(p_range->range[range_id].ref > 1)
    {
        (p_range->range[range_id].ref)--;
    }
    else
    {
        range_ctl.type      = 0;
        range_ctl.min_value = 0;
        range_ctl.max_value = 0;
        range_ctl.is_sudf = p_range->range[range_id].is_sudf;

        if (p_range->is_fg_rg)
        {
            range_ctl.dir = p_range->dir;
            CTC_ERROR_RETURN(sys_usw_acl_set_range_op_ctl(lchip, range_id, &range_ctl));
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_parser_set_range_op_ctl(lchip, range_id, &range_ctl));
        }

        p_range->range[range_id].range_type = ACL_RANGE_TYPE_NONE;
        p_range->range[range_id].min        = 0;
        p_range->range[range_id].max        = 0;
        p_range->range[range_id].ref        = 1;

        (p_range->free_num)++;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_remove_field_range(uint8 lchip, uint8 dir, uint8 range_type, uint8 is_program, uint16* p_range_bitmap)
{
    sys_acl_field_range_t* p_range = NULL;
    uint32 range_id = 0;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    p_range = is_program ?
              p_usw_acl_master[lchip]->field_range[1+dir] :
              p_usw_acl_master[lchip]->field_range[0];
    if (ACL_RANGE_TYPE_NONE == range_type)
    {
        do{
            if (!CTC_IS_BIT_SET(*p_range_bitmap,range_id))
            {
                continue;
            }
            CTC_ERROR_RETURN(_sys_usw_acl_remove_range_bitmap(lchip, p_range, range_id));
        }while(++range_id < SYS_ACL_FIELD_RANGE_NUM);
        *p_range_bitmap = 0;
    }
    else
    {
        do{
            if (!CTC_IS_BIT_SET(*p_range_bitmap,range_id))
            {
                continue;
            }
            if (p_range->range[range_id].range_type == range_type)
            {
                CTC_ERROR_RETURN(_sys_usw_acl_remove_range_bitmap(lchip, p_range, range_id));
                (*p_range_bitmap) &= (~(1 << range_id));
                break;
            }
        }while(++range_id < SYS_ACL_FIELD_RANGE_NUM);
    }
    return CTC_E_NONE;
}

int32
__sys_usw_acl_add_field_range(uint8 lchip, sys_parser_range_op_ctl_t *p_range_ctl, uint16* p_range_bitmap)
{
    uint8 old_range_id    = 0;
    uint8 old_range_valid = 0;
    uint8 range_id        = 0;
    uint8 range_type = 0;
    int32 rt = CTC_E_NONE;
    sys_acl_field_range_t* p_range = NULL;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "  %% PARAM: range_type %u, min %u, max %u\n",
                    p_range_ctl->type, p_range_ctl->min_value, p_range_ctl->max_value);

    p_range = p_range_ctl->is_program ?
              p_usw_acl_master[lchip]->field_range[1+p_range_ctl->dir] :
              p_usw_acl_master[lchip]->field_range[0];

    range_type = p_range_ctl->type;

    if (p_range_ctl->min_value > p_range_ctl->max_value)
    {
        return CTC_E_INVALID_PARAM;
    }

    if (CTC_WB_STATUS(lchip) != CTC_WB_STATUS_RELOADING)
    {
        range_id = 0;
        do {
            if (!CTC_IS_BIT_SET(*p_range_bitmap,range_id))
            {
                continue;
            }
            if (p_range->range[range_id].range_type == range_type)
            {
                old_range_id = range_id;
                old_range_valid = 1;
                break;
            }
        }while(++range_id < SYS_ACL_FIELD_RANGE_NUM);
    }

    if(old_range_valid)
    {
        if( (range_type == p_range->range[old_range_id].range_type) &&
            (p_range_ctl->min_value == p_range->range[old_range_id].min) &&
            (p_range_ctl->max_value == p_range->range[old_range_id].max) &&
            (p_range_ctl->udf_index == p_range->range[old_range_id].udf_index) &&
            (p_range_ctl->udf_sel == p_range->range[old_range_id].udf_sel) &&
            (p_range_ctl->udf_mask == p_range->range[old_range_id].udf_mask) &&
            (p_range_ctl->is_sudf == p_range->range[old_range_id].is_sudf))
        {   /*add a same range twice. do nothing.*/
            return CTC_E_NONE;
        }
        CTC_ERROR_RETURN(_sys_usw_acl_remove_field_range(lchip, p_range_ctl->dir, range_type, p_range_ctl->is_program, p_range_bitmap));
    }
    rt = _sys_usw_acl_add_range_bitmap(lchip, p_range, p_range_ctl, &range_id);
    if(rt < 0)
    {
        if(old_range_valid)
        {
            p_range_ctl->type = range_type;
            p_range_ctl->min_value = p_range->range[old_range_id].min;
            p_range_ctl->max_value = p_range->range[old_range_id].max;
            p_range_ctl->udf_index = p_range->range[old_range_id].udf_index;
            p_range_ctl->udf_sel = p_range->range[old_range_id].udf_sel;
            p_range_ctl->udf_mask = p_range->range[old_range_id].udf_mask;
            p_range_ctl->is_sudf = p_range->range[old_range_id].is_sudf;
            CTC_ERROR_RETURN(_sys_usw_acl_add_range_bitmap(lchip, p_range, p_range_ctl, &range_id));
        }
        else
        {
            return rt;
        }
    }

    /*refresh bitmap/level*/
    (*p_range_bitmap) |= (1 << range_id);

    return rt;
}

int32
_sys_usw_acl_add_field_range(uint8 lchip, uint8 dir, uint8 range_type, uint16 min, uint16 max, uint16* p_range_bitmap)
{
    sys_parser_range_op_ctl_t range_ctl;

    sal_memset(&range_ctl, 0, sizeof(sys_parser_range_op_ctl_t));

    range_ctl.type = range_type;
    range_ctl.min_value = min;
    range_ctl.max_value = max;
    range_ctl.dir = dir;

    return (__sys_usw_acl_add_field_range(lchip, &range_ctl, p_range_bitmap));
}

/*
 * below is build sw struct
 */
#define __ACL_HASH_CALLBACK__


uint32
_sys_usw_acl_hash_make_group(sys_acl_group_t* pg)
{
    return pg->group_id;
}

bool
_sys_usw_acl_hash_compare_group(sys_acl_group_t* pg0, sys_acl_group_t* pg1)
{
    return(pg0->group_id == pg1->group_id);
}

uint32
_sys_usw_acl_hash_make_entry(sys_acl_entry_t* pe)
{
    return pe->fpae.entry_id;
}

bool
_sys_usw_acl_hash_compare_entry(sys_acl_entry_t* pe0, sys_acl_entry_t* pe1)
{
    return(pe0->fpae.entry_id == pe1->fpae.entry_id);
}

uint32
_sys_usw_acl_udf_hash_make_entry(sys_acl_udf_entry_t* pe_sys_udf)
{
    return pe_sys_udf->udf_id;
}

bool
_sys_usw_acl_udf_hash_compare_entry(sys_acl_udf_entry_t* pe0_sys_udf, sys_acl_udf_entry_t* pe1_sys_udf)
{
    return(pe0_sys_udf->udf_id == pe1_sys_udf->udf_id);
}

STATIC uint32
_sys_usw_acl_hash_make_action(sys_acl_hash_action_t* pa_temp)
{
    if (!pa_temp || !pa_temp->ds)
    {
        return 0;
    }
    return ctc_hash_caculate(sizeof(DsFlow_m), pa_temp->ds);
}

STATIC bool
_sys_usw_acl_hash_compare_action(sys_acl_hash_action_t* pa_node, sys_acl_hash_action_t* pa_temp)
{
    uint32 cmd = DRV_IOR(DsFlow_t, DRV_ENTRY_FLAG);
    uint8 lchip = 0;
    DsFlow_m dsflow;

    if (!pa_node || !pa_temp || !pa_temp->ds)
    {
        return FALSE;
    }
    
    lchip = pa_temp->lchip;

    if(pa_node->ad_index == 0xFFFFF) /* if alloc index failed, rollback spool node,so return true */
    {
        return TRUE;
    }

    if(0 != DRV_IOCTL(lchip, pa_node->ad_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &dsflow))
    {
        return FALSE;
    }

    if(!sal_memcmp(&dsflow, pa_temp->ds, DRV_TABLE_ENTRY_SIZE(lchip,DsFlow_t)))
    {
        pa_temp->is_exist = 1;
        return TRUE;
    }

    return FALSE;
}



/* if vlan edit in bucket equals */
STATIC bool
_sys_usw_acl_hash_compare_vlan_edit(sys_acl_vlan_edit_t* pv0,
                                           sys_acl_vlan_edit_t* pv1)
{
    uint32 size = 0;

    if (!pv0 || !pv1)
    {
        return FALSE;
    }

    size = sizeof(sys_acl_vlan_edit_t) - sizeof(uint32);
    if (!sal_memcmp(pv0, pv1, size))
    {
        return TRUE;
    }

    return FALSE;
}

STATIC uint32
_sys_usw_acl_hash_make_vlan_edit(sys_acl_vlan_edit_t* pv)
{
    uint32 size = 0;
    uint8  * k = NULL;

    CTC_PTR_VALID_CHECK(pv);

    size = sizeof(sys_acl_vlan_edit_t) - sizeof(uint32);
    k    = (uint8 *) pv;

    return ctc_hash_caculate(size, k);
}

STATIC bool
_sys_usw_acl_hash_compare_cid_ad(sys_acl_cid_action_t* pa0,
                                           sys_acl_cid_action_t* pa1)
{
    uint32 size = 0;

    if (!pa0 || !pa1)
    {
        return FALSE;
    }

    size = sizeof(sys_acl_cid_action_t) - sizeof(uint32);
    if ((pa0->is_left == pa1->is_left) && !sal_memcmp(pa0, pa1, size))
    {
        return TRUE;
    }

    return FALSE;
}

STATIC uint32
_sys_usw_acl_hash_make_cid_ad(sys_acl_cid_action_t* pa)
{
    uint32 size = sizeof(sys_acl_cid_action_t)-sizeof(pa->ad_index)-sizeof(pa->rsv);
    return ctc_hash_caculate(size, pa);
}



#define __ACL_MAP_UNMAP__

/*
 * check port info if it is valid.
 */
int32
_sys_usw_acl_check_port_info(uint8 lchip, sys_acl_entry_t* pe, ctc_field_key_t* key_field)
{
    uint8  bitmap_status =0;
    uint8  idx;
    uint8  max_pbm_idx = 4;
    uint16* pbm = NULL;
    ctc_field_port_t* p_field_port = (ctc_field_port_t*)key_field->ext_data;

    CTC_PTR_VALID_CHECK(key_field->ext_data);
   /*  CTC_PTR_VALID_CHECK(key_field->ext_mask);*/

    if(key_field->type == CTC_FIELD_KEY_PORT)
	{
        if(CTC_FIELD_PORT_TYPE_GPORT == p_field_port->type)
        {
            SYS_GLOBAL_PORT_CHECK(p_field_port->gport);
        }
        if(CTC_FIELD_PORT_TYPE_PORT_BITMAP == p_field_port->type && (SYS_MAP_LDEV(lchip) != p_field_port->lchip) )
        {
            return CTC_E_NONE;
        }

	}

    if(DRV_FROM_TMM(lchip) || ((CTC_ACL_KEY_COPP != pe->key_type) && (CTC_ACL_KEY_COPP_EXT != pe->key_type) && (CTC_ACL_KEY_UDF != pe->key_type)) )
    {
        bitmap_status = ACL_BITMAP_STATUS_16;
    }
    else
    {
        bitmap_status = ACL_BITMAP_STATUS_64;
    }

    switch(p_field_port->type)
    {
    case CTC_FIELD_PORT_TYPE_PORT_BITMAP:
        if( SYS_ACL_GROUP_IS_PRESEL(pe->group) && pe->ua->buffer.fk && !CTC_ACL_KSET_ISSET(pe->ua->buffer.fk->kset, SYS_ACL_FIELD_PBM))
        {
            return CTC_E_NONE;
        }

        /* tmm portbmp base have 4bit, max port is 16*16=256; TM only support 3 bit, max port is 8*16 = 128 */
        max_pbm_idx = DRV_FROM_AT(lchip) ? 16 : (DRV_FROM_TMM(lchip) ? 8 : 4);
        for (idx = max_pbm_idx; idx < CTC_PORT_BITMAP_IN_WORD; idx++)
        {
            if (p_field_port->port_bitmap[idx])
            {
                return CTC_E_INVALID_PARAM;
            }
        }

        if (ACL_BITMAP_STATUS_64 == bitmap_status)
        {
            if (((p_field_port->port_bitmap[0] || p_field_port->port_bitmap[1]) +
                 (p_field_port->port_bitmap[2] || p_field_port->port_bitmap[3]) +
                 (p_field_port->port_bitmap[4] || p_field_port->port_bitmap[5]) +
                 (p_field_port->port_bitmap[6] || p_field_port->port_bitmap[7]) +
                 (p_field_port->port_bitmap[8] || p_field_port->port_bitmap[9]) +
                 (p_field_port->port_bitmap[10] || p_field_port->port_bitmap[11]) +
                 (p_field_port->port_bitmap[12] || p_field_port->port_bitmap[13]) +
                 (p_field_port->port_bitmap[14] || p_field_port->port_bitmap[15])) > 1)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
        else if (ACL_BITMAP_STATUS_16 == bitmap_status)
        {
            uint8 pbm_unit = 0;
            pbm = (uint16*) p_field_port->port_bitmap;
            for(idx = 0; idx < max_pbm_idx*2; idx++)
            {
                if(pbm[idx])
                {
                    pbm_unit++;
                }
            }
            if (pbm_unit > 1)
            {
                return CTC_E_INVALID_PARAM;
            }
        }

        break;

    case CTC_FIELD_PORT_TYPE_VLAN_CLASS:
        SYS_USW_CLASS_ID_RANGE_CHECK(p_field_port->vlan_class_id);
        break;

    case CTC_FIELD_PORT_TYPE_PORT_CLASS:
        SYS_USW_CLASS_ID_RANGE_CHECK(p_field_port->port_class_id);
        break;

    case CTC_FIELD_PORT_TYPE_L3IF_CLASS:
        SYS_USW_MAX_CLASS_ID_CHECK(p_field_port->l3if_class_id);
        break;

    case CTC_FIELD_PORT_TYPE_LOGIC_PORT:
        SYS_USW_LOGIC_PORT_CHECK(p_field_port->logic_port);
        break;

    case CTC_FIELD_PORT_TYPE_PBR_CLASS:
        CTC_ACL_PBR_CLASS_ID_CHECK(p_field_port->pbr_class_id);
        break;

    case CTC_FIELD_PORT_TYPE_GPORT:
        SYS_GLOBAL_PORT_CHECK(p_field_port->gport);
        break;

    case CTC_FIELD_PORT_TYPE_NONE:
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

/*
 * check group info if it is valid.
 */
STATIC int32
_sys_usw_acl_check_group_info(uint8 lchip, ctc_acl_group_info_t* pinfo, uint8 type, uint8 is_create, uint8 status)
{
    uint8 idx;

    CTC_PTR_VALID_CHECK(pinfo);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_ACL_CHECK_GROUP_PRIO(pinfo->dir, pinfo->priority);
    CTC_MAX_VALUE_CHECK(pinfo->dir, CTC_BOTH_DIRECTION - 1);
    CTC_MAX_VALUE_CHECK(pinfo->key_size, DRV_FROM_TMM(lchip) && pinfo->dir == CTC_INGRESS ? CTC_ACL_KEY_SIZE_480 : CTC_ACL_KEY_SIZE_640);

    switch (type)
    {
    case CTC_ACL_GROUP_TYPE_PORT_BITMAP:

        /* 1. port_bitmap only allow to use 128 bits */
        for (idx = 4; idx < CTC_PORT_BITMAP_IN_WORD; idx++)
        {
            if (pinfo->un.port_bitmap[idx])
            {
                CTC_ERROR_RETURN(CTC_E_INVALID_PARAM);
            }
        }

        if (ACL_BITMAP_STATUS_64 == status)
        {
            if (((pinfo->un.port_bitmap[0] || pinfo->un.port_bitmap[1]) +
                 (pinfo->un.port_bitmap[2] || pinfo->un.port_bitmap[3])) > 1)
            {
                CTC_ERROR_RETURN(CTC_E_INVALID_PARAM);
            }
        }
#if 0
        else if (ACL_BITMAP_STATUS_16 == status)
        {
            if (((pinfo->un.port_bitmap[0] & 0xFFFF || 0) +
                 (pinfo->un.port_bitmap[1] & 0xFFFF || 0) +
                 (pinfo->un.port_bitmap[2] & 0xFFFF || 0) +
                 (pinfo->un.port_bitmap[3] & 0xFFFF || 0) +
                 (pinfo->un.port_bitmap[0] >> 16 || 0) +
                 (pinfo->un.port_bitmap[1] >> 16 || 0) +
                 (pinfo->un.port_bitmap[2] >> 16 || 0) +
                 (pinfo->un.port_bitmap[3] >> 16 || 0)) > 1)
            {
                CTC_ERROR_RETURN(CTC_E_INVALID_PARAM);
            }
        }
#endif
        break;

    case CTC_ACL_GROUP_TYPE_GLOBAL:
        break;

    case CTC_ACL_GROUP_TYPE_NONE:
        break;

    case CTC_ACL_GROUP_TYPE_VLAN_CLASS:
        SYS_USW_CLASS_ID_RANGE_CHECK(pinfo->un.vlan_class_id);
        break;

    case CTC_ACL_GROUP_TYPE_PORT_CLASS:
        SYS_USW_CLASS_ID_RANGE_CHECK(pinfo->un.port_class_id);
        break;

    case CTC_ACL_GROUP_TYPE_L3IF_CLASS:
        SYS_USW_MAX_CLASS_ID_CHECK(pinfo->un.l3if_class_id);
        break;

    case CTC_ACL_GROUP_TYPE_SERVICE_ACL:
        CTC_MAX_VALUE_CHECK(pinfo->un.service_id, MCHIP_CAP(SYS_CAP_ACL_SERVICE_ID_NUM));
        break;

    case CTC_ACL_GROUP_TYPE_HASH: /* check nothing*/
        CTC_MAX_VALUE_CHECK(pinfo->dir, CTC_INGRESS);
        break;

    case CTC_ACL_GROUP_TYPE_PBR_CLASS:
        CTC_ACL_PBR_CLASS_ID_CHECK(pinfo->un.pbr_class_id);
        break;

    case CTC_ACL_GROUP_TYPE_PORT:
        SYS_GLOBAL_PORT_CHECK(pinfo->un.gport);
        break;

    default:
        CTC_ERROR_RETURN(CTC_E_INVALID_PARAM);
    }

    return CTC_E_NONE;
}

/*
 * get sys group info based on ctc group info
 */
STATIC int32
_sys_usw_acl_map_group_info(uint8 lchip, sys_acl_group_info_t* sys, ctc_acl_group_info_t* ctc, uint8 is_create)
{
    if (is_create) /* install group cannot modify: type, priority, direction*/
    {
        sys->type     = ctc->type;
        sys->block_id = ctc->priority;
        sys->dir      = ctc->dir;
        sys->key_size = ctc->key_size;
    }

    if(CTC_ACL_GROUP_TYPE_PORT == sys->type)
    {
        sys->un.gport = ctc->un.gport;
    }
    else
    {
        sal_memcpy(&sys->un, &ctc->un, sizeof(ctc_port_bitmap_t));
        sys->lchip = CTC_MAP_LCHIP(ctc->lchip);
    }

    return CTC_E_NONE;
}


/*
 * get ctc group info based on sys group info
 */
int32
_sys_usw_acl_unmap_group_info(uint8 lchip, ctc_acl_group_info_t* ctc, sys_acl_group_info_t* sys)
{
    ctc->dir      = sys->dir;
    ctc->type     = sys->type;
    ctc->priority = sys->block_id;
    ctc->lchip    = SYS_MAP_LDEV(lchip);

    if(CTC_ACL_GROUP_TYPE_PORT == sys->type)
    {
        ctc->un.gport = sys->un.gport;
    }
    else
    {
        sal_memcpy(&ctc->un, &sys->un, sizeof(ctc_port_bitmap_t));
    }

    return CTC_E_NONE;
}

/*
 * remove accessory property
 */
STATIC int32
_sys_usw_acl_remove_accessory_property(uint8 lchip, sys_acl_entry_t* pe)
{
    return _sys_usw_acl_remove_field_range(lchip, pe->group->group_info.dir, ACL_RANGE_TYPE_NONE, SYS_ACL_GROUP_IS_PRESEL(pe->group), &pe->un.g4.range_bitmap);
}

#define  __ACL_BUILD_FREE_INDEX__

/* build index of HASH ad */
STATIC int32
_sys_usw_acl_build_hash_ad_index(sys_acl_hash_action_t* pa_node, uint8* p_lchip)
{
    uint32 value_32 = 0;
    sys_usw_opf_t opf;
    int32 ret = CTC_E_NONE;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = *p_lchip;
#endif
    CTC_PTR_VALID_CHECK(pa_node);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_acl_master[*p_lchip]->opf_type_ad;
    if (CTC_WB_STATUS(*p_lchip) == CTC_WB_STATUS_RELOADING)
    {
        ret = sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, pa_node->ad_index);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "hash_ad_index_from_position=%d\n", pa_node->ad_index);
    }
    else
    {
        ret = sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32);
        pa_node->ad_index = (ret == CTC_E_NONE)? (value_32 & 0xFFFFF):0xFFFFF;/* 0xFFFF: invalid index */
    }

    return ret;
}

/* free index of HASH ad */
STATIC int32
_sys_usw_acl_free_hash_ad_index(sys_acl_hash_action_t* pa_node, uint8* p_lchip)
{
    sys_usw_opf_t opf;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = *p_lchip;
#endif
    CTC_PTR_VALID_CHECK(pa_node);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_acl_master[*p_lchip]->opf_type_ad;

    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, pa_node->ad_index));

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_acl_build_vlan_edit_index(sys_acl_vlan_edit_t* pv, uint8* p_lchip)
{
    sys_usw_opf_t opf;
    uint32               value_32 = 0;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = pv->is_global;
    opf.pool_type  = p_usw_acl_master[*p_lchip]->opf_type_vlan_edit;
    if (CTC_WB_STATUS(*p_lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, pv->profile_id));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32));
        pv->profile_id = value_32 & 0xFFFF;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_free_vlan_edit_index(sys_acl_vlan_edit_t* pv, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = pv->is_global;
    opf.pool_type  = p_usw_acl_master[*p_lchip]->opf_type_vlan_edit;

    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, (uint32) pv->profile_id));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_build_cid_ad_index(sys_acl_cid_action_t* pa, uint8* p_lchip)
{
    sys_usw_opf_t opf;
    uint32               value_32 = 0;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    if(pa->is_left)
    {
        opf.pool_index = 0;
    }
    else
    {
        opf.pool_index = 1;
    }
    opf.pool_type  = p_usw_acl_master[*p_lchip]->opf_type_cid_ad;
    if ( CTC_WB_STATUS(*p_lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, pa->ad_index));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32));
        pa->ad_index = value_32 & 0xFFFF;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_free_cid_ad_index(sys_acl_cid_action_t* pa, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    if(pa->is_left)
    {
        opf.pool_index = 0;
    }
    else
    {
        opf.pool_index = 1;
    }
    opf.pool_type = p_usw_acl_master[*p_lchip]->opf_type_cid_ad;

    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, pa->ad_index));

    return CTC_E_NONE;
}


#define  __ACL_ESSENTIAL_API__


STATIC int32
_sys_usw_acl_alloc_tcam_entry(uint8 lchip, sys_acl_group_t* pg, sys_acl_entry_t* pe)
{
    uint8   block_id = 0;
    uint8   key_size = 0;
    uint8   step     = 0;
    uint8   key_used_bitmap = 0;
    uint8   real_step = 0;

    sys_acl_block_t * pb        = NULL;
    uint32          block_index = 0;

    /* get block index. */
    _sys_usw_acl_get_key_size(lchip, 1, pe, &real_step);
    key_size = _sys_usw_acl_get_key_size(lchip, 0, pe, &step);

    block_id = pg->group_info.block_id;
    if(CTC_EGRESS == pg->group_info.dir)
    {
        block_id += p_usw_acl_master[lchip]->igs_block_num;
    }

    pb = &(SYS_ACL_BLOCK(lchip, block_id));

    if (DRV_IS_DUET2(lchip) || DRV_IS_TSINGMA(lchip))   /*TMM...not care*/
    {
        _sys_usw_acl_get_key_size_bitmap(lchip, pb, &key_used_bitmap, pe->group->group_info.dir);
        if ((CTC_IS_BIT_SET(key_used_bitmap, CTC_FPA_KEY_SIZE_80) && (CTC_FPA_KEY_SIZE_80 != key_size)) || \
            (!CTC_IS_BIT_SET(key_used_bitmap, CTC_FPA_KEY_SIZE_80) && key_used_bitmap && (CTC_FPA_KEY_SIZE_80 == key_size)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Tcam key 80 can't be used with others!\n");
            return CTC_E_NOT_SUPPORT;
        }
    }

    if(SYS_USW_ACL_UPA_EN(lchip, pe->group->group_info.dir))
    {
        CTC_ERROR_RETURN(pb->fpab.free_count < step? CTC_E_NO_RESOURCE: CTC_E_NONE);
        (pb->fpab.free_count) -= step;
        (pb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_80]) -= (CTC_FPA_KEY_SIZE_80 == key_size)? 1: 0;
        block_index = pe->fpae.priority;
    }
    else
    {

        CTC_ERROR_RETURN(fpa_usw_alloc_offset(p_usw_acl_master[lchip]->fpa, &pb->fpab, key_size,
                                    pe->fpae.priority, &block_index));

    }
    /* add to block */
    pb->fpab.entries[block_index] = &pe->fpae;

    /* set block index */
    pe->fpae.offset_a = block_index;
    pe->fpae.step     = step;
    pe->fpae.real_step = real_step;

    return CTC_E_NONE;

}


int32
_sys_usw_acl_update_key_count(uint8 lchip, sys_acl_entry_t* pe, uint8 is_add)
{
    int8 cnt = 1;
    sys_acl_flex_key_t* p_fk= NULL;

    if(!is_add)
    {
        cnt = -1;
    }

    if(SYS_ACL_KEY_IS_FLEX_HASH0(pe->action_type, pe->key_type, pe->group->group_info.block_id))
    {
        p_fk = SYS_ACL_GET_FK(lchip, pe);
        cnt *= ((sys_acl_flex_hash_t*)p_fk)->key_size/2;
        p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_HASH] += cnt;
    }
    else if(SYS_ACL_GROUP_IS_PRESEL(pe->group) && ACL_ENTRY_IS_TCAM(pe))
    {
        p_fk = SYS_ACL_GET_FK(lchip, pe);
        cnt *= p_fk->key_size;
        
        p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_160] += cnt;
        return CTC_E_NONE;
    }

    switch(pe->key_type)
    {
        case CTC_ACL_KEY_INTERFACE:
            p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_80] += cnt;
            break;

        case CTC_ACL_KEY_CID:
        case CTC_ACL_KEY_MAC:
        case CTC_ACL_KEY_IPV4:
            p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_160] += cnt;
            break;

        case CTC_ACL_KEY_IPV6:
        case CTC_ACL_KEY_IPV4_EXT:
        case CTC_ACL_KEY_MAC_IPV4:
        case CTC_ACL_KEY_FWD:
        case CTC_ACL_KEY_COPP:
            p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_320] += cnt;
            break;

        case CTC_ACL_KEY_IPV6_EXT:
        case CTC_ACL_KEY_MAC_IPV6:
        case CTC_ACL_KEY_MAC_IPV4_EXT:
        case CTC_ACL_KEY_FWD_EXT:
        case CTC_ACL_KEY_COPP_EXT:
            p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_640] += cnt;
            break;

        case CTC_ACL_KEY_HASH_MAC:
        case CTC_ACL_KEY_HASH_IPV4:
        case CTC_ACL_KEY_HASH_MPLS:
        case CTC_ACL_KEY_HASH_NSH:
            p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_HASH] += cnt;
            break;

        case CTC_ACL_KEY_HASH_L2_L3:
        case CTC_ACL_KEY_HASH_IPV6:
            p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_HASH] += (cnt + cnt);
            break;

        default:
            break;
    }


    return CTC_E_NONE;
}

/*
 * pe, pg, pb are lookup result.
 */
STATIC int32
_sys_usw_acl_remove_tcam_entry(uint8 lchip, sys_acl_entry_t* pe_lkup,
                                      sys_acl_group_t* pg_lkup,
                                      sys_acl_block_t* pb_lkup)
{
    uint8  part = 0;
    uint8 global_pp_en = 0;
    sys_acl_flex_key_t* fk = NULL;
    sys_acl_vlan_edit_t* vlan_edit = NULL;
    if(!pb_lkup)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "remove_tcam_entry abnormal,fpae is not exist\n");

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid configuration \n");
        return CTC_E_INVALID_CONFIG;

    }
    fk = pe_lkup->ua->buffer.fk;
    vlan_edit = pe_lkup->ua->buffer.ad.tcam.vlan_edit;
    if (NULL != vlan_edit)
    {
        CTC_ERROR_RETURN(ctc_spool_remove(p_usw_acl_master[lchip]->vlan_edit_spool, vlan_edit, NULL));
    }

    if (pe_lkup->un.g4.ether_type_valid != 0 && MCHIP_ACL(lchip)->remove_compress_ether_type && SYS_ACL_GROUP_IS_PRESEL(pg_lkup))
    {

        if (!CTC_ACL_KSET_ISSET(fk->kset, SYS_ACL_FIELD_FULL_ETHER_TYPE))
        {
            global_pp_en = SYS_ACL_IS_GLOBAL_PP_EN_LKUP(lchip, pg_lkup->group_info.dir, pg_lkup->group_info.block_id);
            CTC_ERROR_RETURN(MCHIP_ACL(lchip)->remove_compress_ether_type(lchip, global_pp_en, pe_lkup->group->group_info.dir, pe_lkup->un.g4.ether_type_index));
        }
    }
    else if(pe_lkup->un.g4.ether_type_valid != 0)
    {
        CTC_ERROR_RETURN(sys_usw_register_remove_compress_ether_type(lchip, pe_lkup->un.g4.ether_type_index));
    }

    /* remove from group */
    ctc_list_pointer_delete(&(pg_lkup->entry_list), &(pe_lkup->head));
    /* remove from hash */
    ctc_hash_remove(p_usw_acl_master[lchip]->entry, pe_lkup);

    /* remove accessory property */
    _sys_usw_acl_remove_accessory_property(lchip, pe_lkup);

    /* free index */
    if(SYS_USW_ACL_UPA_EN(lchip, pe_lkup->group->group_info.dir))
    {
        uint8 step = 0;
        uint8 key_size = 0;

        key_size = _sys_usw_acl_get_key_size(lchip, 0, pe_lkup, &step);
        if (SYS_ACL_GROUP_IS_PRESEL(pe_lkup->group))
        {
            SYS_ACL_PART_LOOP(part, pb_lkup->fpab.part_num)
            {
                if (part < key_size)
                {
                    pb_lkup[part].fpab.free_count++;
                    pb_lkup[part].fpab.sub_free_count[CTC_FPA_KEY_SIZE_160]++;
                    pb_lkup[part].fpab.entries[pe_lkup->fpae.offset_a] = NULL;
                }
            }
        }
        else
        {
            (pb_lkup->fpab.free_count) += step;
            (pb_lkup->fpab.sub_free_count[CTC_FPA_KEY_SIZE_80]) += (CTC_FPA_KEY_SIZE_80 == key_size)? 1: 0;
            pb_lkup->fpab.entries[pe_lkup->fpae.offset_a] = NULL;
        }
        /* add to block */

    }
    else
    {
        /*1.  Alloc TCAM index */
        if (SYS_ACL_GROUP_IS_PRESEL(pg_lkup))
        {
            CTC_ERROR_RETURN(MCHIP_ACL(lchip)->free_tcam_entry(lchip, pg_lkup, pe_lkup));
        }
        else
        {
            fpa_usw_free_offset(&pb_lkup->fpab, pe_lkup->fpae.offset_a);
        }
    }

    _sys_usw_acl_update_key_count(lchip, pe_lkup, 0);

    (pg_lkup->entry_count)--;

    /* remove action_data */
    if(pe_lkup->ua->buffer.pa)
    {
        mem_free(pe_lkup->ua->buffer.pa);
        pe_lkup->ua->buffer.pa = NULL;
    }

    /* free aset */
    _sys_usw_acl_remove_aset(lchip, pe_lkup->aset_id);

    /* remove buffer */
    sys_usw_acl_buffer_malloc(lchip, pe_lkup, FALSE);

    /* memory free */
    mem_free(pe_lkup);

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_acl_remove_hash_entry(uint8 lchip, sys_acl_hash_entry_t* pe_lkup,
                                      sys_acl_group_t* pg_lkup,
                                      sys_acl_block_t* pb_lkup)
{
    uint32      key_id  = 0;
    uint32      hw_index = 0;
    drv_acc_in_t   in;
    drv_acc_out_t  out;

    /* remove from group */
    ctc_list_pointer_delete(&(pg_lkup->entry_list), &(pe_lkup->head));
    /* remove from hash */
    ctc_hash_remove(p_usw_acl_master[lchip]->entry, pe_lkup);


    _sys_usw_acl_update_key_count(lchip, (void*)pe_lkup, 0);

    /* clear hw */
    if((pe_lkup->key_index != 0) && (pe_lkup->key_index != 0xFFFFFF))
    {
        SYS_ACL_GET_TBL_FUNC(lchip, ACL_SHARE_PTR(pe_lkup,sys_acl_entry_t), &key_id, NULL, &hw_index);
        sal_memset(&in, 0, sizeof(in));
        sal_memset(&out, 0, sizeof(out));

        in.type     = DRV_ACC_TYPE_DEL;
        in.op_type  = DRV_ACC_OP_BY_INDEX;
        in.tbl_id   = key_id;
        in.index    = hw_index;
        in.module = DRV_ACC_HASH_MODULE_FLOW;
        in.oper_bmp = DRV_ACC_BMP_EN(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL));
        CTC_ERROR_RETURN(drv_acc_api(lchip, &in, &out));
    }

    /* remove buffer */
    if (pe_lkup->ua->buffer.pa)
    {
        mem_free(pe_lkup->ua->buffer.pa);
    }
    sys_usw_acl_buffer_malloc(lchip,(void*)pe_lkup,FALSE);

    (pg_lkup->entry_count)--;

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_acl_add_tcam_entry_db(uint8 lchip, sys_acl_group_t* pg, sys_acl_entry_t* pe)
{
    uint8 acl_priority = pg->group_info.block_id;
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    /*1.  Alloc TCAM index */
    if (SYS_ACL_GROUP_IS_PRESEL(pg))
    {
        CTC_ERROR_RETURN(MCHIP_ACL(lchip)->alloc_tcam_entry(lchip, pg, pe));
        pe->ua->buffer.fk->entry_count[acl_priority]++;
    }
    else
    {
        sys_acl_fixed_key_t* fk = ACL_SHARE_PTR(pe->ua->buffer.fk, sys_acl_fixed_key_t);
        CTC_ERROR_RETURN(_sys_usw_acl_alloc_tcam_entry(lchip, pg, pe));
        if (NULL != fk)
        {
            fk->entry_count++;
        }
    }

    /*2. Add to DB and upate stats */
    ctc_hash_insert(p_usw_acl_master[lchip]->entry, pe);

	ctc_list_pointer_insert_head(&(pg->entry_list), &(pe->head));

    pe->fpae.flag = FPA_ENTRY_FLAG_UNINSTALLED;
    (pg->entry_count)++;

    _sys_usw_acl_update_key_count(lchip, pe, 1);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_add_hash_entry_db(uint8 lchip, sys_acl_group_t* pg, sys_acl_hash_entry_t* pe)
{
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    /* add to hash */
    ctc_hash_insert(p_usw_acl_master[lchip]->entry, pe);

    /* add to group */
    ctc_list_pointer_insert_head(&(pg->entry_list), &(pe->head));
    /* set flag */
    pe->installed = FALSE;

    (pg->entry_count)++;

    return CTC_E_NONE;
}

#define __ACL_DUMP_INFO__

/*1:tag_op; 0:tag_sl; */
const char*
_sys_usw_get_vlan_edit_desc(uint8 is_tag_op, uint8 type)
{
    if(1 == is_tag_op)
    {
        switch (type)
        {
            case CTC_ACL_VLAN_TAG_OP_NONE:
                return "None";
            case CTC_ACL_VLAN_TAG_OP_REP:
                return "Replace";
            case CTC_ACL_VLAN_TAG_OP_ADD:
                return "Add";
            case CTC_ACL_VLAN_TAG_OP_DEL:
                return "Delete";
            case CTC_ACL_VLAN_TAG_OP_REP_OR_ADD:
                return "Replace or add";
            default:
                return "Error type";
        }
    }
    else
    {
        switch (type)
        {
            case CTC_VLAN_TAG_SL_AS_PARSE:
                return "As parser";
            case CTC_VLAN_TAG_SL_ALTERNATIVE:
                return "Alternative";
            case CTC_VLAN_TAG_SL_NEW:
                return "New";
            case CTC_VLAN_TAG_SL_DEFAULT:
                return "Default";
            default:
                return "Error type";
        }
    }
    return NULL;
}

int32
_sys_usw_acl_get_action_field(uint8 lchip, uint32 entry_id, ctc_acl_field_action_t* p_field_action)
{
    sys_acl_entry_t* pe = NULL;
    sys_acl_aset_t*  aset = NULL;

    SYS_ACL_INIT_CHECK();
    CTC_PTR_VALID_CHECK(p_field_action);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "  %% PARAM: entry_id %u field_action_type %u\n", entry_id, p_field_action->type);

    p_field_action->data1 = 0;
    _sys_usw_acl_get_entry_by_eid(lchip, entry_id, &pe);
    if(pe && pe->ua && !pe->ua_type)
    {
        aset = pe->ua->buffer.aset;
        if(!CTC_BMP_ISSET(aset->w, p_field_action->type))
        {
            p_field_action->data0 = 0;
            p_field_action->data1 = 0;
            return CTC_E_NOT_EXIST;
        }
        CTC_ERROR_RETURN(p_usw_acl_master[lchip]->get_ad_func[pe->action_type](lchip, p_field_action, pe));
        /* ext_data use data1 for action valid */
        if((p_field_action->ext_data || p_field_action->data0 == 0) && p_field_action->data1 == 0)
        {
            return CTC_E_NOT_EXIST;
        }
    }
    else
    {
        return CTC_E_NOT_EXIST;
    }

    return CTC_E_NONE;
}

const char*
_sys_usw_get_color_desc(uint8 color_type)
{
    switch (color_type)
    {
        case CTC_QOS_COLOR_NONE:
            return "None";
        case CTC_QOS_COLOR_RED:
            return "Red";
        case CTC_QOS_COLOR_YELLOW:
            return "Yellow";
        case CTC_QOS_COLOR_GREEN:
            return "Green";
        default:
            return "Error color";
    }
    return NULL;
}

const char*
_sys_usw_get_cp_to_cpu_desc(uint8 cp_to_cpu_type)
{
    switch (cp_to_cpu_type)
    {
        case CTC_ACL_TO_CPU_MODE_TO_CPU_NOT_COVER:
            return "Not Cover Cpu Reason";
        case CTC_ACL_TO_CPU_MODE_TO_CPU_COVER:
            return "Cover Cpu Reason";
        case CTC_ACL_TO_CPU_MODE_CANCEL_TO_CPU:
            return "Cancel To CPU";
        default:
            return "Error color";
    }
    return NULL;
}

 /* 1: gport*/
 /* 2: logical port*/
STATIC int32
_sys_usw_acl_hash_port_type_judge(uint8 lchip, uint8 key_type,uint8 hash_sel_id)
{
    ds_t ds_sel ={0};
    fld_id_t field_id;
    uint32 table_id = 0;
    uint32 drv_data_temp[4] ={0};
    uint32 cmd = 0;

    CTC_MAX_VALUE_CHECK(hash_sel_id, 0xF);
    switch(key_type)
    {
    case CTC_ACL_KEY_HASH_MAC:
        table_id = FlowL2HashFieldSelect_t;
        break;
    case CTC_ACL_KEY_HASH_IPV4:
        table_id = FlowL3Ipv4HashFieldSelect_t;
        break;
    case CTC_ACL_KEY_HASH_L2_L3:
        table_id = FlowL2L3HashFieldSelect_t;
        break;
    case CTC_ACL_KEY_HASH_MPLS:
        table_id = FlowL3MplsHashFieldSelect_t;
        break;
    case CTC_ACL_KEY_HASH_IPV6:
        table_id = FlowL3Ipv6HashFieldSelect_t;
        break;
    case CTC_ACL_KEY_HASH_NSH:
        table_id = FlowNshHashFieldSelect_t;
        break;
    default:
        return CTC_E_INTR_INVALID_PARAM;
    }
    cmd = DRV_IOR(table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, hash_sel_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), ds_sel));

    CTC_ERROR_RETURN(drv_usw_get_field_id_by_sub_string(lchip, table_id, &field_id, "globalPortType"));
    DRV_GET_FIELD(lchip, table_id, field_id, ds_sel, drv_data_temp);

    if (ACL_HASH_GPORT_TYPE_GPORT == drv_data_temp[0])
    {
        return 1;
    }
    else if(ACL_HASH_GPORT_TYPE_LOGIC_PORT == drv_data_temp[0])
    {
        return 2;
    }

    return CTC_E_NONE;

}

 /*data_type: 1 uint32; 2 ext_data*/
STATIC int32
sys_usw_acl_map_key_field_to_field_name(uint8 lchip, sys_acl_entry_t* pe, uint16 key_field_type, uint32 key_id, uint8* data_type, char** field_name, uint8* start_bit, uint8* bit_len, uint8* field_name_cnt, char** print_str, uint32* p_key_size)
{
    uint32 drv_data_temp[4] = {0,0,0,0};
    uint8 is_hash = !ACL_ENTRY_IS_TCAM(pe);
    fld_id_t field_id;
    char* str = NULL;
    uint32 key_size = 4;
    uint8 copp_ext_key_ip_mode = 0;
    uint32 cmd = 0;
    FlowTcamLookupCtl_m flow_ctl;
    CTC_MAX_VALUE_CHECK(key_field_type,CTC_FIELD_KEY_NUM);
    CTC_PTR_VALID_CHECK(field_name);
    CTC_PTR_VALID_CHECK(start_bit);
    CTC_PTR_VALID_CHECK(bit_len);

    *data_type = 1;
    start_bit[0] = 0;
    bit_len[0]   = 32;
    start_bit[1] = 0;
    bit_len[1]   = 0;
    *field_name_cnt = 1;

    cmd = DRV_IOR(FlowTcamLookupCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &flow_ctl);

    copp_ext_key_ip_mode =  GetFlowTcamLookupCtl(V, coppKeyIpAddrShareType0_f,&flow_ctl);

    switch(key_field_type)
    {
        /*Ether  field*/
        case CTC_FIELD_KEY_MAC_SA:
            if (CTC_ACL_KEY_FWD_EXT == pe->key_type)
            {
                field_name[0] = "u1_g1_macSa";
            }
            else
            {
                field_name[0] = "macSa";
            }
            str = "Mac Sa";
            *data_type = 2;
            key_size = sizeof(mac_addr_t);
            break;
        case CTC_FIELD_KEY_MAC_DA:
            if (CTC_ACL_KEY_FWD_EXT == pe->key_type)
            {
                field_name[0] = "u1_g1_macDa";
            }
            else
            {
                field_name[0] = "macDa";
            }
            str = "Mac Da";
            *data_type = 2;
            key_size = sizeof(mac_addr_t);
            break;
        case CTC_FIELD_KEY_SVLAN_ID:
            {
                if (DRV_FROM_TMM(lchip) && (CTC_ACL_KEY_MAC_IPV6 == pe->key_type || CTC_ACL_KEY_MAC_IPV4 == pe->key_type || CTC_ACL_KEY_MAC_IPV4_EXT == pe->key_type))
                {
                    field_name[0] = "vlanId";
                }
                else if (CTC_ACL_KEY_HASH_L2_L3 == pe->key_type || CTC_ACL_KEY_MAC_IPV4 == pe->key_type || CTC_ACL_KEY_MAC_IPV4_EXT == pe->key_type || CTC_ACL_KEY_MAC_IPV6 == pe->key_type)
                {
                    field_name[0] = "svlanId";
                }
                else if (CTC_ACL_KEY_FWD_EXT == pe->key_type)
                {
                    field_name[0] = "u1_g1_svlanId";
                }
                else
                {
                    field_name[0] = "vlanId";
                }
                str = "Svlan ID";
                break;
            }
        case CTC_FIELD_KEY_CVLAN_ID:
            {
                if (CTC_ACL_KEY_HASH_L2_L3 == pe->key_type || CTC_ACL_KEY_MAC_IPV4 == pe->key_type || CTC_ACL_KEY_MAC_IPV4_EXT == pe->key_type || CTC_ACL_KEY_MAC_IPV6 == pe->key_type)
                {
                    field_name[0] = "cvlanId";
                }
                else if (CTC_ACL_KEY_FWD_EXT == pe->key_type)
                {
                    field_name[0] = "u1_g1_cvlanId";
                }
                else
                {
                    field_name[0] = "vlanId";
                }
                str = "Cvlan ID";
                break;
            }
            /*IP packet field*/
        case CTC_FIELD_KEY_IP_SA:
            {
                switch(pe->key_type)
                {
                case CTC_ACL_KEY_CID:            /* ipSa	32 */
                case CTC_ACL_KEY_MAC_IPV4_EXT:
                case CTC_ACL_KEY_MAC_IPV4:
                case CTC_ACL_KEY_IPV4:
                case CTC_ACL_KEY_IPV4_EXT:
                case CTC_ACL_KEY_HASH_IPV4:
                case CTC_ACL_KEY_HASH_L2_L3:
                case CTC_ACL_KEY_FWD_EXT:        /* ipSa 128 0-31 */
                    field_name[0] = "ipSa";      /* CTC_ACL_KEY_FWD_EXT:ipSa 128 0-31; other ipSa 32*/
                    break;
                case CTC_ACL_KEY_COPP:           /* ipAddr  128 0-31 */
                case CTC_ACL_KEY_COPP_EXT:       /* ipAddr  32 */
                    field_name[0] = "ipAddr";
                    break;
                case CTC_ACL_KEY_FWD:            /*ipAddr1  64 0-31 */
                    field_name[0] = "ipAddr2";
                    break;
                default:
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
                    return CTC_E_NOT_SUPPORT;
                }
                str = "IP SA";
                break;
            }
        case CTC_FIELD_KEY_IP_DA:
            {
                switch(pe->key_type)
                {
                case CTC_ACL_KEY_CID:            /* ipDa	32 */
                case CTC_ACL_KEY_MAC_IPV4_EXT:
                case CTC_ACL_KEY_MAC_IPV4:
                case CTC_ACL_KEY_IPV4:
                case CTC_ACL_KEY_IPV4_EXT:
                case CTC_ACL_KEY_HASH_IPV4:
                case CTC_ACL_KEY_HASH_L2_L3:
                case CTC_ACL_KEY_FWD_EXT:        /* ipDa	128 0-31 */
                    field_name[0] = "ipDa";      /* CTC_ACL_KEY_FWD_EXT:ipDa	128 0-31; other ipDa 32 */
                    break;
                case CTC_ACL_KEY_COPP:           /* ipAddr  128 0-31 */
                case CTC_ACL_KEY_COPP_EXT:       /* ipAddr  32 */
                    field_name[0] = "ipAddr";
                    break;
                case CTC_ACL_KEY_FWD:            /* ipAddr1  64 0-31 */
                    field_name[0] = "ipAddr1";
                    break;
                default:
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
                    return CTC_E_NOT_SUPPORT;
                }
                str = "IP DA";
                break;
            }
        case CTC_FIELD_KEY_IPV6_SA:
            {
                switch(pe->key_type)
                {
                case CTC_ACL_KEY_MAC_IPV6:
                    if (DRV_FROM_TMM(lchip))
                    {
                        field_name[0] = "u1_g1_ipSa";
                        bit_len[0]   = 32;
                        field_name[1] = "ipSa127To32";
                        bit_len[1]   = 96;
                        *field_name_cnt = 2;
                    }
                    else if (!DRV_FLD_IS_EXISIT(DsAclQosMacIpv6Key640_t, DsAclQosMacIpv6Key640_ipSa_f))
                    {
                        field_name[0] = "ipSa31To0";
                        bit_len[0]   = 32;
                        field_name[1] = "ipSa127To32";
                        bit_len[1]   = 96;
                        *field_name_cnt = 2;
                    }
                    break;
                case CTC_ACL_KEY_IPV6_EXT:
                    if (DRV_FLD_IS_EXISIT(DsAclQosIpv6Key640_t, DsAclQosIpv6Key640_ipSa_f))
                    {
                        field_name[0] = "ipSa";          /* AclQosIpv6Key640, MacIpv6Key640, fwd640   128 */
                    }
                    else
                    {
                        field_name[0] = "ipAddr1";
                        bit_len[0]   = 64;
                        field_name[1] = "ipAddr2";
                        bit_len[1]   = 64;
                        *field_name_cnt = 2;
                    }
                    break;
                case CTC_ACL_KEY_FWD_EXT:
                     /* case CTC_ACL_KEY_HASH_IPV6:*/
                    field_name[0] = "ipSa";          /* AclQosIpv6Key640, MacIpv6Key640, fwd640   128 */
                    break;
                case CTC_ACL_KEY_COPP_EXT:
                    if(copp_ext_key_ip_mode)
                    {
                        field_name[0] = "ipAddr";           /* copp640  128 */
                    }
                    else
                    {
                        field_name[0] = "udf";
                    }
                    break;
                case CTC_ACL_KEY_FWD:
                case CTC_ACL_KEY_IPV6:
                    field_name[0] = "ipAddr2";       /* fwd320   64 */
                    break;
                case CTC_ACL_KEY_CID:
                    field_name[0] = "u1_g2_ipAddr";    /* cid160   64 ipSa;  u1_g2_ipAddr, u1_g2_ipAddrMode*/
                    break;
                case CTC_ACL_KEY_HASH_IPV6:
                    field_name[0] = "u1_g1_ipSa";    /* AclQosIpv6Key320   64  no need special process */
                    break;
                default:
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
                    return CTC_E_NOT_SUPPORT;
                }
                str = "IPV6 SA";
                 *data_type = 2;
                 key_size = sizeof(ipv6_addr_t);
                break;
            }
        case CTC_FIELD_KEY_IPV6_DA:
            {
                switch(pe->key_type)
                {
                case CTC_ACL_KEY_MAC_IPV6:
                    if (DRV_FROM_TMM(lchip))
                    {
                        field_name[0] = "u1_g1_ipDa";
                        bit_len[0]   = 32;
                        field_name[1] = "ipDa127To32";
                        bit_len[1]   = 96;
                        *field_name_cnt = 2;
                    }
                    else if (!DRV_FLD_IS_EXISIT(DsAclQosMacIpv6Key640_t, DsAclQosMacIpv6Key640_ipDa_f))
                    {
                        field_name[0] = "ipDa31To0";
                        bit_len[0]   = 32;
                        field_name[1] = "ipDa127To32";
                        bit_len[1]   = 96;
                        *field_name_cnt = 2;
                    }
                    break;
                case CTC_ACL_KEY_IPV6_EXT:
                case CTC_ACL_KEY_FWD_EXT:
                     /* case CTC_ACL_KEY_HASH_IPV6:*/
                    field_name[0] = "ipDa";          /* AclQosIpv6Key640, MacIpv6Key640, fwd640   128 */
                    break;
                case CTC_ACL_KEY_COPP_EXT:
                    if(copp_ext_key_ip_mode)
                    {
                        field_name[0] = "udf";        /* copp640  128; cid160   64 */
                    }
                    else
                    {
                        field_name[0] = "ipAddr";
                    }
                    break;
                case CTC_ACL_KEY_CID:
                    field_name[0] = "u1_g2_ipAddr";    /* cid160   64; u1_g2_ipAddr, u1_g2_ipAddrMode */
                    break;
                case CTC_ACL_KEY_FWD:
                case CTC_ACL_KEY_IPV6:
                    field_name[0] = "ipAddr1";       /* fwd320   64 */
                    break;
                case CTC_ACL_KEY_HASH_IPV6:
                    field_name[0] = "u1_g1_ipDa";    /* AclQosIpv6Key320   64 */
                    break;
                default:
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
                    return CTC_E_NOT_SUPPORT;
                }
                str = "IPV6 DA";
                 *data_type = 2;
                 key_size = sizeof(ipv6_addr_t);
                break;
            }
            /*TCP/UDP packet field*/
        case CTC_FIELD_KEY_L4_DST_PORT:
            field_name[0] = "l4DestPort";
            str = "L4 DST PORT";
            break;
        case CTC_FIELD_KEY_L4_SRC_PORT:
            if (CTC_ACL_KEY_UDF == pe->key_type)
            {
                field_name[0] = "l4SrcPort";
            }
            else
            {
                field_name[0] = "l4SourcePort";
            }
            str = "L4 SRC PORT";
            break;
            /*GRE packet field*/
        case CTC_FIELD_KEY_GRE_KEY:
            {
                if ((CTC_ACL_KEY_HASH_IPV4 == pe->key_type)||
                    (DRV_FROM_TMM(lchip)&&(CTC_ACL_KEY_IPV4_EXT==pe->key_type||
                                           CTC_ACL_KEY_IPV6==pe->key_type||
                                           CTC_ACL_KEY_IPV6_EXT==pe->key_type)))
                {
                    field_name[0] = "greKey";
                }
                else if (DRV_FROM_TMM(lchip)&&(CTC_ACL_KEY_MAC_IPV4_EXT==pe->key_type||CTC_ACL_KEY_MAC_IPV6==pe->key_type))
                {
                    field_name[0] = "vxlanFlags";
                    bit_len[0]   = 8;
                    field_name[1] = "vxlanVni";
                    bit_len[1]   = 24;
                    *field_name_cnt = 2;
                }
                else
                {
                    field_name[0] = "l4DestPort";
                    start_bit[0] = 0;
                    bit_len[0]   = 16;
                    field_name[1] = "l4SourcePort";
                    start_bit[1] = 0;
                    bit_len[1]   = 16;
                    *field_name_cnt = 2;
                }
                str = "GRE KEY";
                break;
            }
        case CTC_FIELD_KEY_VN_ID:
            {
                if (CTC_ACL_KEY_HASH_IPV4 == pe->key_type || CTC_ACL_KEY_HASH_L2_L3 == pe->key_type || CTC_ACL_KEY_HASH_IPV6 == pe->key_type)
                {
                    field_name[0] = "vni";
                }
                else if (DRV_FROM_TMM(lchip)&&(CTC_ACL_KEY_IPV4_EXT == pe->key_type||
                                               CTC_ACL_KEY_MAC_IPV4_EXT == pe->key_type||
                                               CTC_ACL_KEY_IPV6 == pe->key_type||
                                               CTC_ACL_KEY_IPV6_EXT == pe->key_type||
                                               CTC_ACL_KEY_MAC_IPV6 == pe->key_type))
                {
                    field_name[0] = "vxlanVni";
                }
                else
                {
                    field_name[0] = "l4DestPort";
                    start_bit[0] = 0;
                    bit_len[0]   = 16;
                    field_name[1] = "l4SourcePort";
                    start_bit[1] = 0;
                    bit_len[1]   = 8;
                    *field_name_cnt = 2;
                }
                str = "VN ID";
                break;
            }
        case CTC_FIELD_KEY_MPLS_LABEL0:
            if (CTC_ACL_KEY_HASH_L2_L3 == pe->key_type || CTC_ACL_KEY_HASH_MPLS == pe->key_type)
            {
                field_name[0] = "mplsLabel0";
            }
            else
            {
                field_name[0] = "mplsLabel0";
                start_bit[0] = 12;
                bit_len[0]   = 20;
            }
            str = "Mpls Label0";
            break;
        case CTC_FIELD_KEY_MPLS_LABEL1:
            if (CTC_ACL_KEY_HASH_L2_L3 == pe->key_type || CTC_ACL_KEY_HASH_MPLS == pe->key_type)
            {
                field_name[0] = "mplsLabel1";
            }
            else
            {
                field_name[0] = "mplsLabel1";
                start_bit[0] = 12;
                bit_len[0]   = 20;
            }
            str = "Mpls Label1";
            break;
        case CTC_FIELD_KEY_MPLS_LABEL2:
            if (CTC_ACL_KEY_HASH_L2_L3 == pe->key_type || CTC_ACL_KEY_HASH_MPLS == pe->key_type)
            {
                field_name[0] = "mplsLabel2";
            }
            else
            {
                field_name[0] = "mplsLabel2";
                start_bit[0] = 12;
                bit_len[0]   = 20;
            }
            str = "Mpls Label2";
            break;
            /*Match port type*/
        case CTC_FIELD_KEY_PORT:
            {
                if (CTC_ACL_KEY_COPP == pe->key_type || CTC_ACL_KEY_COPP_EXT == pe->key_type)
                {
                    *data_type = 2;  /*special process */
                    field_name[1] = "portBase";
                    bit_len[1]   = 1;
                    field_name[0] = "portBitmap";
                    bit_len[0]   = 64;
                    *field_name_cnt = 2;
                    str = "Port Bitmap(Base/Value)";
                    break;
                }
                if (CTC_ACL_KEY_UDF == pe->key_type)
                {
                    if(drv_usw_get_field_id_by_sub_string(lchip, key_id, &field_id, "logicPort") == DRV_E_NONE)
                    {
                        DRV_GET_FIELD(lchip, key_id, field_id, pe->ua->buffer.mask, drv_data_temp);
                        if (0 != drv_data_temp[0])
                        {
                            field_name[0] = "logicPort";
                            str = "Logic Port";
                            break;
                        }
                        else
                        {
                            *data_type = 2;  /*special process */
                            field_name[1] = "portBase";
                            bit_len[1]   = 1;
                            field_name[0] = "portBitmap";
                            bit_len[0]   = 64;
                            *field_name_cnt = 2;
                            str = "Port Bitmap(Base/Value)";
                            break;
                        }
                    }
                }
                else
                {
                    *data_type = 1;  /*special process */
                    if (is_hash)
                    {
                        if (1 == _sys_usw_acl_hash_port_type_judge(lchip, pe->key_type, ACL_SHARE_PTR(pe, sys_acl_hash_entry_t)->hash_field_sel_id))
                        {
                            field_name[0] = "globalSrcPort";
                            str = "Gport";
                            break;
                        }
                        else if(2 == _sys_usw_acl_hash_port_type_judge(lchip, pe->key_type, ACL_SHARE_PTR(pe, sys_acl_hash_entry_t)->hash_field_sel_id))
                        {
                            field_name[0] = "globalSrcPort";
                            str = "Logical port";
                            break;
                        }
                    }
                    else
                    {
                        if(drv_usw_get_field_id_by_sub_string(lchip, key_id, &field_id, "globalPortType") == DRV_E_NONE)
                        {
                            DRV_GET_FIELD(lchip, key_id, field_id, pe->ua->buffer.key, drv_data_temp);
                            if ((DRV_ENUM(DRV_FLOWPORTTYPE_GPORT) == drv_data_temp[0])
                                || (DRV_ENUM(DRV_FLOWPORTTYPE_LPORT) == drv_data_temp[0]))
                            {
                                if (DRV_IS_DUET2(lchip) && (CTC_ACL_KEY_MAC_IPV4_EXT == pe->key_type || CTC_ACL_KEY_IPV6_EXT == pe->key_type || CTC_ACL_KEY_MAC_IPV6 == pe->key_type || CTC_ACL_KEY_FWD_EXT == pe->key_type))
                                {
                                    field_name[1] = "globalPort15To8";
                                    bit_len[1]   = 8;
                                    field_name[0] = "globalPort7To0";
                                    bit_len[0]   = 8;
                                    *field_name_cnt = 2;
                                }
                                else
                                {
                                    field_name[0] = "globalPort";
                                }
                                str = (DRV_ENUM(DRV_FLOWPORTTYPE_GPORT) == drv_data_temp[0])?"Gport":"Logical port";
                                break;
                            }
                            else if(DRV_ENUM(DRV_FLOWPORTTYPE_BITMAP) == drv_data_temp[0])
                            {
                                if (DRV_IS_DUET2(lchip) && (CTC_ACL_KEY_MAC_IPV4_EXT == pe->key_type || CTC_ACL_KEY_IPV6_EXT == pe->key_type || CTC_ACL_KEY_MAC_IPV6 == pe->key_type || CTC_ACL_KEY_FWD_EXT == pe->key_type))
                                {
                                    field_name[2] = "globalPort15To8";
                                    bit_len[2]   = 8;
                                    field_name[1] = "globalPort7To0";
                                    bit_len[1]   = 8;
                                    field_name[0] = "portBitmap";
                                    bit_len[0]   = 3;
                                    *field_name_cnt = 3;
                                }
                                else if(CTC_ACL_KEY_COPP == pe->key_type || CTC_ACL_KEY_COPP_EXT == pe->key_type)
                                {
                                    field_name[1] = "portBase";
                                    bit_len[1]   = 1;
                                    field_name[0] = "portBitmap";
                                    bit_len[0]   = 64;
                                    *field_name_cnt = 2;
                                }
                                else
                                {
                                    field_name[1] = "globalPort";
                                    bit_len[1]   = 16;
                                    field_name[0] = "portBitmap";
                                    bit_len[0]   = DRV_FROM_TMM(lchip)?4: 3;
                                    *field_name_cnt = 2;
                                }
                                str = "Port Bitmap(Base/Value)";
                                break;
                            }
                            else if (!DRV_IS_DUET2(lchip))
                            {
                                if(drv_usw_get_field_id_by_sub_string(lchip, key_id, &field_id, "portBitmap") == DRV_E_NONE)
                                {
                                    DRV_GET_FIELD(lchip, key_id, field_id, pe->ua->buffer.key, drv_data_temp);
                                    if (0 != drv_data_temp[0])
                                    {
                                        field_name[1] = "portBase";
                                        bit_len[1] = 1;
                                        field_name[0] = "portBitmap";
                                        bit_len[0] = 64;
                                        *field_name_cnt = 2;
                                        str = "Port Bitmap(Base/Value)";
                                    }
                                    else
                                    {
                                        if(drv_usw_get_field_id_by_sub_string(lchip, key_id, &field_id, "logicPort") == DRV_E_NONE)
                                        {
                                            DRV_GET_FIELD(lchip, key_id, field_id, pe->ua->buffer.key, drv_data_temp);
                                            if (0 != drv_data_temp[0])
                                            {
                                                field_name[0] = "logicPort";
                                                *field_name_cnt = 1;
                                                str = "Logical port";
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            key_size = sizeof(ctc_field_port_t);
            break;
        case CTC_FIELD_KEY_CLASS_ID:
            if( ACL_ENTRY_IS_TCAM(pe) && CTC_ACL_KEY_COPP != pe->key_type && CTC_ACL_KEY_COPP_EXT != pe->key_type
                && drv_usw_get_field_id_by_sub_string(lchip, key_id, &field_id, "aclLabel") == DRV_E_NONE)
            {
                DRV_GET_FIELD(lchip, key_id, field_id, pe->ua->buffer.mask, drv_data_temp);
                if (0 != drv_data_temp[0])
                {
                    field_name[0] = "aclLabel";
                    str = "Class ID";
                }
            }
            /*Forwarding information*/
            break;
        case CTC_FIELD_KEY_FID:
            field_name[0] = "fid";
            str = "FORWARD ID";
            break;
        case CTC_FIELD_KEY_DST_GPORT:
            field_name[0] = "destMap";
            str = "DST GPORT";
            break;
        case CTC_FIELD_KEY_NSH_SI:
            field_name[0] = "nshSphSi";
            str = "NSH SI";
            break;
        case CTC_FIELD_KEY_NSH_SPI:
            field_name[0] = "nshSphSpi";
            str = "NSH SPI";
            break;
        default:
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
			return CTC_E_NOT_SUPPORT;
    }
    if(print_str)
    {
        *print_str = str;
    }
    if(p_key_size)
    {
        *p_key_size  = key_size;
    }
    return CTC_E_NONE;
}

/* return: 1   not add the key field */
int32
_sys_usw_acl_get_key_field_value(uint8 lchip, sys_acl_entry_t* pe, uint16 key_field_type, uint32 key_id, ctc_field_key_t* p_field_key, char** print_str, uint32* key_size)
{
    char* field_name[4] = {NULL};
    fld_id_t field_id;
    uint8 start_bit[4] = {0};
    uint8 bit_len[4] = {0};
    uint8 field_name_cnt = 0;
    uint8 field_valid = 0;
    uint32 drv_data_temp[4] = {0,0,0,0};
    uint32 drv_mask_temp[4] = {0,0,0,0};
    uint32 drv_ext_data_temp[4] = {0,0,0,0};
    uint32 hw_ipv6_64[2] = {0};
    uint32 shift = 0;
    int32 field_name_i= 0;
    uint8 data_type = 0;
    ctc_field_port_t field_port;
    uint32 temp_field_data = 0;
    uint32 temp_field_mask = 0;
    CTC_PTR_VALID_CHECK(pe->ua);

    sal_memset(&field_port, 0, sizeof(ctc_field_port_t));

    if(CTC_ACL_KEY_CID == pe->key_type &&  CTC_FIELD_KEY_L4_USER_TYPE == key_field_type)  /* CTC_ACL_KEY_CID not support CTC_FIELD_KEY_L4_USER_TYPE */
    {
        return 1;
    }

    //if(!CTC_BMP_ISSET(pe->key_bmp, key_field_type) && (key_field_type != CTC_FIELD_KEY_CLASS_ID || !CTC_BMP_ISSET(pe->key_bmp, CTC_FIELD_KEY_PORT)))
    if(ACL_ENTRY_IS_TCAM(pe) && pe->ua->buffer.fk)
    {
        sys_acl_fixed_key_t* p_fixed_key = (void*)pe->ua->buffer.fk;

        if(!CTC_BMP_ISSET(p_fixed_key->kset.w, key_field_type) && (key_field_type != CTC_FIELD_KEY_CLASS_ID || !CTC_BMP_ISSET(p_fixed_key->kset.w, CTC_FIELD_KEY_PORT)))
        {
            return 1;
        }
    }

    if(!ACL_ENTRY_IS_TCAM(pe)) /*hash only show sel field*/
    {
        sys_acl_hash_entry_t* pe_hash = ACL_SHARE_PTR(pe, sys_acl_hash_entry_t);
        if( sys_usw_acl_get_hash_field_sel(lchip, pe_hash->key_type, pe_hash->hash_field_sel_id, key_field_type, &field_valid) != CTC_E_NONE )
        {
            return 1;
        }

        /* for hash mac key, cvlan, svlan, must select one of two */
        if(pe_hash->key_type == CTC_ACL_KEY_HASH_MAC)
        {
            if((pe_hash->mac_key_vlan_mode == 1 && key_field_type == CTC_FIELD_KEY_CVLAN_ID)
               || (pe_hash->mac_key_vlan_mode == 2 && key_field_type == CTC_FIELD_KEY_SVLAN_ID)
               || (pe_hash->mac_key_vlan_mode == 0 && (key_field_type == CTC_FIELD_KEY_SVLAN_ID || key_field_type == CTC_FIELD_KEY_CVLAN_ID)))
            {
                return 1;
            }
        }

        if(!field_valid)
        {
            return 1;
        }
    }

    sys_usw_acl_map_key_field_to_field_name(lchip, pe, key_field_type, key_id,&data_type, field_name, start_bit, bit_len, &field_name_cnt, print_str, key_size);
    p_field_key->data = 0;
    p_field_key->mask = 0;

    for (field_name_i = 0; field_name_i < field_name_cnt; field_name_i++)
    {
        sal_memset(drv_data_temp, 0, sizeof(drv_data_temp));
        sal_memset(drv_mask_temp, 0, sizeof(drv_mask_temp));
        if ((NULL == field_name[field_name_i]))
        {
            break;
        }

        if(drv_usw_get_field_id_by_sub_string(lchip, key_id, &field_id, field_name[field_name_i]) != DRV_E_NONE)
        {
            return 1;
        }
        DRV_GET_FIELD(lchip, key_id, field_id, pe->ua->buffer.key, drv_data_temp);
        DRV_GET_FIELD(lchip, key_id, field_id, pe->ua->buffer.mask, drv_mask_temp);

        if (!DRV_IS_DUET2(lchip) && CTC_ACL_KEY_MAC_IPV6 == pe->key_type && (CTC_FIELD_KEY_IPV6_SA == key_field_type || CTC_FIELD_KEY_IPV6_DA == key_field_type))
        {
            if (!field_name_i)
            {
                temp_field_data = drv_data_temp[0];
                temp_field_mask = drv_mask_temp[0];
                continue;
            }
            else
            {
                drv_data_temp[3] = drv_data_temp[2];
                drv_data_temp[2] = drv_data_temp[1];
                drv_data_temp[1] = drv_data_temp[0];
                drv_data_temp[0] = temp_field_data;
                drv_mask_temp[3] = drv_mask_temp[2];
                drv_mask_temp[2] = drv_mask_temp[1];
                drv_mask_temp[1] = drv_mask_temp[0];
                drv_mask_temp[0] = temp_field_mask;
            }
        }

        if (1 == data_type)
        {

            if((CTC_FIELD_KEY_IP_SA==key_field_type) && (CTC_ACL_KEY_COPP_EXT==pe->key_type)) /*DsAclQosCoppKey640; CTC_FIELD_KEY_IP_SA:ipAddr 128 32-63; CTC_FIELD_KEY_IP_DA: ipAddr  128 0-31   */
            {
                p_field_key->data = drv_data_temp[1];
                p_field_key->mask = drv_mask_temp[1];
            }
            else /* field_key.data; first is low bits; later is high bits */
            {
                p_field_key->data |= ((drv_data_temp[0]>>start_bit[field_name_i])&((1LLU<<bit_len[field_name_i])-1))<<shift;
                p_field_key->mask |= ((drv_mask_temp[0]>>start_bit[field_name_i])&((1LLU<<bit_len[field_name_i])-1))<<shift;
                shift += bit_len[field_name_i];
            }
            if ((CTC_FIELD_KEY_DST_GPORT == key_field_type) || (0 == sal_strcasecmp(*print_str,"Gport")))
            {
                uint16 lport = 0;
                uint8  gchip = 0;
                lport = p_field_key->data & 0x1FF;
                gchip = (p_field_key->data >> 9)&0x7F;
                p_field_key->data = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
            }
        }
        else
        {/* field_key.ext_data */
            if ((CTC_ACL_KEY_COPP == pe->key_type || CTC_ACL_KEY_COPP_EXT == pe->key_type || CTC_ACL_KEY_UDF == pe->key_type) && (0 == sal_strcasecmp(*print_str, "Port Bitmap(Base/Value)")))
            {
                if (0 == field_name_i)  /*CTC_ACL_KEY_COPP, CTC_ACL_KEY_COPP_EXT port-bitmap 64*2*/
                {
                    drv_ext_data_temp[0] = *(uint32*)drv_mask_temp;        /* drv_data_temp[0]*/
                    drv_ext_data_temp[1] = *((uint32*)drv_mask_temp + 1);  /* drv_data_temp[1]*/
                }
                else /* base:(drv_data_temp[0]&0x1)*/
                {
                    drv_ext_data_temp[2] = *((uint32*)drv_data_temp)& 0x1;
                    sal_memcpy(p_field_key->ext_data, drv_ext_data_temp, sizeof(drv_ext_data_temp));
                    sal_memcpy(p_field_key->ext_mask, drv_ext_data_temp, sizeof(drv_ext_data_temp));
                }
            }
            else if (DRV_FROM_TMM(lchip) && (CTC_ACL_KEY_IPV6_EXT == pe->key_type) && (CTC_FIELD_KEY_IPV6_SA == key_field_type))
            {
                if (0 == field_name_i)
                {
                    drv_ext_data_temp[0] = drv_data_temp[0];
                    drv_ext_data_temp[1] = drv_data_temp[1];
                    drv_ext_data_temp[2] = drv_mask_temp[0];
                    drv_ext_data_temp[3] = drv_mask_temp[1];
                }
                else
                {
                    drv_data_temp[2] = drv_data_temp[0];
                    drv_data_temp[3] = drv_data_temp[1];
                    drv_data_temp[0] = drv_ext_data_temp[0];
                    drv_data_temp[1] = drv_ext_data_temp[1];
                    drv_mask_temp[2] = drv_mask_temp[0];
                    drv_mask_temp[3] = drv_mask_temp[1];
                    drv_mask_temp[0] = drv_ext_data_temp[2];
                    drv_mask_temp[1] = drv_ext_data_temp[3];
                    SYS_USW_REVERT_IP6((uint32*)p_field_key->ext_data, (uint32*)drv_data_temp);
                    SYS_USW_REVERT_IP6((uint32*)p_field_key->ext_mask, (uint32*)drv_mask_temp);
                }
            }
            else if ((CTC_ACL_KEY_FWD == pe->key_type || CTC_ACL_KEY_IPV6 == pe->key_type || CTC_ACL_KEY_CID == pe->key_type)
                && (CTC_FIELD_KEY_IPV6_SA == key_field_type || CTC_FIELD_KEY_IPV6_DA == key_field_type))
            {
                SYS_USW_REVERT_BYTE(hw_ipv6_64, drv_data_temp);
                _sys_usw_acl_get_ipv6_addr_from_compress(lchip, pe, (CTC_FIELD_KEY_IPV6_DA == key_field_type), hw_ipv6_64, (uint32*)p_field_key->ext_data);

                SYS_USW_REVERT_BYTE(hw_ipv6_64, drv_mask_temp);
                _sys_usw_acl_get_ipv6_addr_from_compress(lchip, pe, (CTC_FIELD_KEY_IPV6_DA == key_field_type), hw_ipv6_64, (uint32*)p_field_key->ext_mask);
            }
            else
            {
                switch(key_field_type)
                {/* process data format to user */
                    case CTC_FIELD_KEY_MAC_SA:
                    case CTC_FIELD_KEY_MAC_DA:
                    case CTC_FIELD_KEY_SENDER_MAC:
                    case CTC_FIELD_KEY_TARGET_MAC:
                    case CTC_FIELD_KEY_WLAN_RADIO_MAC:
                        SYS_USW_SET_USER_MAC((uint8*)p_field_key->ext_data, (uint32*)drv_data_temp);
                        SYS_USW_SET_USER_MAC((uint8*)p_field_key->ext_mask, (uint32*)drv_mask_temp);
                        break;
                    case CTC_FIELD_KEY_IPV6_SA:
                    case CTC_FIELD_KEY_IPV6_DA:
                        SYS_USW_REVERT_IP6((uint32*)p_field_key->ext_data, (uint32*)drv_data_temp);
                        SYS_USW_REVERT_IP6((uint32*)p_field_key->ext_mask, (uint32*)drv_mask_temp);
                        break;
                    default:
                        break;
                }
            }
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_show_key(uint8 lchip, sys_acl_entry_t* pe, uint32 key_id, ctc_field_key_t* p_grep, uint8 grep_cnt)
{
    ctc_field_key_t field_key;
    uint8 data_temp[SYS_USW_ACL_MAX_KEY_SIZE] = {0};
    uint8 mask_temp[SYS_USW_ACL_MAX_KEY_SIZE] = {0};
    uint32 ipv6_address[4] = {0, 0, 0, 0};
    uint16 key_field_recored_i = 0;
    uint16 show_key_field_array[] = {CTC_FIELD_KEY_PORT,CTC_FIELD_KEY_DST_GPORT,CTC_FIELD_KEY_SVLAN_ID,CTC_FIELD_KEY_CVLAN_ID,
                                                        CTC_FIELD_KEY_MAC_SA,CTC_FIELD_KEY_MAC_DA,CTC_FIELD_KEY_IP_SA,CTC_FIELD_KEY_IP_DA,
                                                        CTC_FIELD_KEY_IPV6_SA,CTC_FIELD_KEY_IPV6_DA,CTC_FIELD_KEY_L4_SRC_PORT,CTC_FIELD_KEY_L4_DST_PORT,
                                                        CTC_FIELD_KEY_GRE_KEY,CTC_FIELD_KEY_VN_ID,CTC_FIELD_KEY_MPLS_LABEL0,CTC_FIELD_KEY_MPLS_LABEL1,
                                                        CTC_FIELD_KEY_MPLS_LABEL2,CTC_FIELD_KEY_CLASS_ID,CTC_FIELD_KEY_NSH_SPI,CTC_FIELD_KEY_NSH_SI};
    uint8  show_key_field_array_i = 0;
    uint8  grep_i = 0;
    uint32 tempip = 0;
    char buf[CTC_IPV6_ADDR_STR_LEN];
    uint32 tempip_mask = 0;
    char buf_mask[CTC_IPV6_ADDR_STR_LEN];
    char* print_str = NULL;
    uint8 is_tcam = ACL_ENTRY_IS_TCAM(pe);
    uint8 pgrep_result =0;

    CTC_PTR_VALID_CHECK(pe);
    sal_memset(&field_key, 0, sizeof(ctc_field_key_t));

    field_key.ext_data = data_temp;
    field_key.ext_mask = mask_temp;
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Primary Key(Value/Mask):\n");

    if(MCHIP_ACL(lchip)->show_flex_hash_field && !ACL_ENTRY_IS_TCAM(pe) && pe->ua->buffer.fk)
    {
        return MCHIP_ACL(lchip)->show_flex_hash_field(lchip, (sys_acl_hash_entry_t*)pe);
    }

    for (show_key_field_array_i = 0; show_key_field_array_i < sizeof(show_key_field_array)/sizeof(uint16); show_key_field_array_i++)
    {
        key_field_recored_i = show_key_field_array[show_key_field_array_i];
        if (0 != grep_cnt) /* when grep, only printf these which are greped */
        {
            pgrep_result = 0;
            for (grep_i = 0; grep_i < grep_cnt; grep_i++)
            {
                if(key_field_recored_i == p_grep[grep_i].type)
                {
                    pgrep_result = 1;
                }
            }
            if(0 == pgrep_result)
            {
                continue;
            }
        }

        if ((1 == _sys_usw_acl_get_key_field_value(lchip, pe, key_field_recored_i, key_id, &field_key, &print_str, NULL))
            || (NULL == print_str)
            || ((CTC_ACL_KEY_COPP == pe->key_type || CTC_ACL_KEY_COPP_EXT == pe->key_type) && (CTC_FIELD_KEY_L3_TYPE == key_field_recored_i) && (0==field_key.data && 0==field_key.mask)))
        {
            continue;
        }

        if(ACL_ENTRY_IS_TCAM(pe))
        {
            if(!field_key.mask && field_key.ext_mask)
            {
                if(sys_usw_acl_array_is_empty((uint8*)field_key.ext_mask, (sizeof(field_key.ext_mask)<<2)))
                {
                    continue;
                }
            }
        }

        if (key_field_recored_i == CTC_FIELD_KEY_MAC_SA || key_field_recored_i == CTC_FIELD_KEY_MAC_DA || key_field_recored_i == CTC_FIELD_KEY_TARGET_MAC || key_field_recored_i == CTC_FIELD_KEY_SENDER_MAC || key_field_recored_i == CTC_FIELD_KEY_WLAN_RADIO_MAC)
        {
            if(is_tcam)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %x.%x.%x/%X.%X.%X \n", print_str, sal_ntohs(*(unsigned short*)field_key.ext_data), sal_ntohs(*((unsigned short*)(field_key.ext_data) + 1)), sal_ntohs(*((unsigned short*)(field_key.ext_data) + 2)),sal_ntohs(*(unsigned short*)field_key.ext_mask), sal_ntohs(*((unsigned short*)(field_key.ext_mask) + 1)), sal_ntohs(*((unsigned short*)(field_key.ext_mask) + 2)));
            }
            else
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %x.%x.%x \n", print_str, sal_ntohs(*(unsigned short*)field_key.ext_data), sal_ntohs(*((unsigned short*)(field_key.ext_data) + 1)), sal_ntohs(*((unsigned short*)(field_key.ext_data) + 2)));
            }
        }
        else if(key_field_recored_i == CTC_FIELD_KEY_IP_SA || key_field_recored_i == CTC_FIELD_KEY_IP_DA || key_field_recored_i == CTC_FIELD_KEY_ARP_SENDER_IP || key_field_recored_i == CTC_FIELD_KEY_ARP_TARGET_IP)
        {
            tempip = sal_ntohl(field_key.data);
            sal_inet_ntop(AF_INET, &tempip, buf, CTC_IPV6_ADDR_STR_LEN);
            if (is_tcam)
            {
                tempip_mask = sal_ntohl(field_key.mask);
                sal_inet_ntop(AF_INET, &tempip_mask, buf_mask, CTC_IPV6_ADDR_STR_LEN);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %-15s/%-15s \n", print_str, buf, buf_mask);
            }
            else
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %-15s\n", print_str, buf);
            }
        }
        else if(key_field_recored_i == CTC_FIELD_KEY_IPV6_SA || key_field_recored_i == CTC_FIELD_KEY_IPV6_DA)
        {
            ipv6_address[0] = sal_ntohl(*((uint32*)field_key.ext_data));
            ipv6_address[1] = sal_ntohl(*((uint32*)field_key.ext_data+1));
            ipv6_address[2] = sal_ntohl(*((uint32*)field_key.ext_data+2));
            ipv6_address[3] = sal_ntohl(*((uint32*)field_key.ext_data+3));
            sal_inet_ntop(AF_INET6, ipv6_address, buf, CTC_IPV6_ADDR_STR_LEN);
            if (is_tcam)
            {
                sal_memset(ipv6_address, 0, sizeof(uint32)*4);
                ipv6_address[0] = sal_ntohl(*((uint32*)field_key.ext_mask));
                ipv6_address[1] = sal_ntohl(*((uint32*)field_key.ext_mask+1));
                ipv6_address[2] = sal_ntohl(*((uint32*)field_key.ext_mask+2));
                ipv6_address[3] = sal_ntohl(*((uint32*)field_key.ext_mask+3));
                sal_inet_ntop(AF_INET6, ipv6_address, buf_mask, CTC_IPV6_ADDR_STR_LEN);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %s/%s\n", print_str, buf, buf_mask);
            }
            else
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %s\n", print_str, buf);
            }
        }
        else
        {
            if ((CTC_FIELD_KEY_PORT == key_field_recored_i) &&(0 == sal_strcasecmp(print_str,"Port Bitmap(Base/Value)")))
            {
                if(CTC_ACL_KEY_COPP == pe->key_type || CTC_ACL_KEY_COPP_EXT == pe->key_type || CTC_ACL_KEY_UDF == pe->key_type)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u, 0x%"PRIx64"\n", print_str, ((*((uint32*)field_key.ext_data + 2))&0x1)*64, ~(uint64)(((uint64)(*((uint32*)field_key.ext_mask + 1))<<32) | (*((uint32*)field_key.ext_mask))));
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u, 0x%x\n", print_str, ((field_key.data>>16)&0x7)*16, ~field_key.mask & 0xFFFF);
                }
            }
            else
            {
                if (is_tcam)
                {
                    if ((CTC_FIELD_KEY_DST_GPORT == key_field_recored_i) || (0 == sal_strcasecmp(print_str,"Gport")))
                    {
                        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: 0x%x/0x%X\n", print_str, field_key.data, field_key.mask);
                    }
                    else
                    {
                        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u/0x%X\n", print_str, field_key.data, field_key.mask);
                    }
                }
                else
                {
                    if ((CTC_FIELD_KEY_DST_GPORT == key_field_recored_i) || (0 == sal_strcasecmp(print_str,"Gport")))
                    {
                        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: 0x%x\n", print_str, field_key.data);
                    }
                    else
                    {
                        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", print_str, field_key.data);
                    }
                }
            }
        }
        print_str = NULL;
    }
    return CTC_E_NONE;
}

/*
show acl action
*/
STATIC int32
_sys_usw_acl_show_action(uint8 lchip, sys_acl_entry_t* pe)
{
    int32 ret = 0;
    char* const color[4] = {"G", "Y", "R", ""};
    uint8 color_index = 0;
    uint8 is_half_ad = 0;
    ctc_acl_vxlan_rsv_edit_t vxlan_rsv_edit;
    ctc_acl_timestamp_t timestamp;
    ctc_acl_field_action_t field_action;
    ctc_acl_to_cpu_t       copy_to_cpu;
    ctc_acl_ipfix_t        ipfix;
    ctc_acl_oam_t          oam;
    ctc_acl_lb_hash_t      lb_hash;
    ctc_acl_inter_cn_t     inter_cn;
    ctc_acl_vlan_edit_t    vlan_edit;
    ctc_acl_packet_strip_t strip_pkt;
    ctc_acl_table_map_t    table_map;
    ctc_acl_int_t          acl_int;
    ctc_xdata_t  xdata;
    ctc_xdata_field_t      fields[9];
    uint8 loop = 0;
    ctc_xdata_field_t* p_field = NULL;

    CTC_PTR_VALID_CHECK(pe);
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    sal_memset(&copy_to_cpu, 0, sizeof(ctc_acl_to_cpu_t));
    sal_memset(&ipfix, 0, sizeof(ctc_acl_ipfix_t));
    sal_memset(&oam, 0, sizeof(ctc_acl_oam_t));
    sal_memset(&lb_hash, 0, sizeof(ctc_acl_lb_hash_t));
    sal_memset(&inter_cn, 0, sizeof(ctc_acl_inter_cn_t));
    sal_memset(&vlan_edit, 0, sizeof(ctc_acl_vlan_edit_t));
    sal_memset(&strip_pkt, 0, sizeof(ctc_acl_packet_strip_t));
    sal_memset(&table_map, 0, sizeof(ctc_acl_table_map_t));
    sal_memset(&acl_int, 0, sizeof(ctc_acl_int_t));
    sal_memset(&xdata, 0, sizeof(ctc_xdata_t));
    sal_memset(&fields, 0, sizeof(fields));
    xdata.fields = fields;
    sal_memset(&vxlan_rsv_edit, 0, sizeof(ctc_acl_vxlan_rsv_edit_t));
    sal_memset(&timestamp, 0, sizeof(ctc_acl_timestamp_t));

    if( CTC_ACL_KEY_INTERFACE == pe->key_type && !DRV_FROM_TMM(lchip))
    {
        is_half_ad = 1;
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nAction:\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-------------------------------------\n");

    field_action.type = CTC_ACL_FIELD_ACTION_STATS;      /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        if (DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u, Not CareDiscard: %d\n", "STATS ID", field_action.data0, field_action.data1);
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "STATS ID", field_action.data0);
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_SERVICE_ID;      /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "SERVICE ID", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "MPLS IM FLOW ID", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_RANDOM_LOG;   /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        if (DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: Log Id:%u, Session Id:%u, Percent:%s%d\n",
                                                  "RANDOM LOG",
                                                  field_action.data0>>2,
                                                  field_action.data0&3,
                                                  "1/2^",
                                                  CTC_LOG_PERCENT_POWER_NEGATIVE_0-field_action.data1);
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: Log Id:%u,Percent:%s%d\n",
                                                  "RANDOM LOG",
                                                  field_action.data0,
                                                  "1/2^",
                                                  CTC_LOG_PERCENT_POWER_NEGATIVE_0-field_action.data1);
        }

    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_COLOR;     /* only tcam have*/
    if (DRV_FROM_TMM(lchip) && (pe->action_type == SYS_ACL_ACTION_TCAM_INGRESS))
    {
        color_index = 0;
        SYS_ACL_SHOW_AD_WITH_COLOR(lchip, pe->fpae.entry_id, field_action, "COLOR", field_action.data0, SYS_ACL_SHOW_SUB_STR(color, color_index, field_action.data1, "", FALSE, field_action.data1 ));
    }
    else if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %s\n", "COLOR",_sys_usw_get_color_desc(field_action.data0));
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_MICRO_FLOW_POLICER;    /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "MICRO FLOW POLICER PTR", field_action.data0);
        if (DRV_FROM_TMM(lchip))
        {
            sys_qos_policer_group_info_t policer_group_info;
            sal_memset(&policer_group_info, 0, sizeof(sys_qos_policer_group_info_t));
            policer_group_info.dir = pe->group->group_info.dir;
            policer_group_info.policer_member_ptr = field_action.data0;
            CTC_ERROR_RETURN(sys_usw_qos_policer_group_check_bind(lchip, &policer_group_info));
            if (policer_group_info.is_bind && policer_group_info.policer_group_ptr)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "MACRO FLOW POLICER PTR", policer_group_info.policer_group_ptr);
            }
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_MACRO_FLOW_POLICER;    /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "MACRO FLOW POLICER PTR", field_action.data0);
    }
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_COS_HBWP_POLICER;    /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "HBWP POLICER PTR", field_action.data0);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "COS INDEX", field_action.data1);
    }
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_COPP;                  /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "COPP PTR", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_SRC_CID;               /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "SRC_CID", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_TRUNCATED_LEN;         /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "TRUNCATED_LEN", field_action.data0);
    }

    /* tcam and hash both have*/
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_REDIRECT_PORT;   /* only tcam have*/
    if(_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        field_action.type = CTC_ACL_FIELD_ACTION_REDIRECT;   /* only tcam have*/
        _sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action);
    }
    if (field_action.data0) /*redirect port*/
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u(NH-ID) %s:0x%.4x\n", "REDIRECT", field_action.data0, "gport", field_action.data1);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_REDIRECT_CANCEL_PKT_EDIT;   /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "REDIRECT_CANCEL_PKT_EDIT");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_REDIRECT_FILTER_ROUTED_PKT;  /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "REDIRECT_FILTER_ROUTED_PKT");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DISCARD;              /* tcam and hash both have, but not same*/
    if (!ACL_ENTRY_IS_TCAM(pe) || is_half_ad)
    {
        field_action.data0 = CTC_QOS_COLOR_GREEN;
        ret = _sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action);
        if(!ret && field_action.data1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s:","DISCARD");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-2s","G");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-2s","Y");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-2s","R");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
        }
    }
    else
    {
        color_index = 0;
        SYS_ACL_SHOW_AD_WITH_COLOR(lchip, pe->fpae.entry_id, field_action, "DISCARD", field_action.data0, SYS_ACL_SHOW_SUB_STR(color, color_index, 0, "", TRUE, field_action.data1));
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CANCEL_DISCARD;     /* only tcam have*/
    if ( is_half_ad)
    {
        field_action.data0 = CTC_QOS_COLOR_GREEN;
        ret = _sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action);
        if(!ret && field_action.data1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s:","CANCEL DISCARD");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-2s","G");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-2s","Y");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-2s\n","R");
        }
    }
    else
    {
        color_index = 0;
        SYS_ACL_SHOW_AD_WITH_COLOR(lchip, pe->fpae.entry_id, field_action, "CANCEL DISCARD", field_action.data0, SYS_ACL_SHOW_SUB_STR(color, color_index, 0, "", TRUE, field_action.data1));
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DISABLE_ELEPHANT_LOG;  /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "DISABLE_ELEPHANT_LOG");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_TERMINATE_CID_HDR;    /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "TERMINATE_CID_HDR");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CANCEL_NAT;           /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "CANCEL_NAT");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CANCEL_IPFIX;        /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "CANCEL_IPFIX");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CANCEL_IPFIX_LEARNING;   /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "CANCEL_IPFIX_LEARNING");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CANCEL_DOT1AE;      /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "CANCEL_DOT1AE");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DOT1AE_PERMIT_PLAIN_PKT;    /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "DOT1AE_PERMIT_PLAIN_PKT");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_METADATA;        /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "METADATA", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_FID;        /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "FID", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CRITICAL_PKT;   /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        if (DRV_FROM_TM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-25s\n", field_action.data0==1? "CRITICAL_PKT": field_action.data0==2? "CANCEL_CRITICAL_PKT": "NONE");
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n", "CRITICAL_PKT");
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_LOGIC_PORT;    /*only hash have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "LOGIC_PORT", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_SPAN_FLOW;    /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "SPAN_FLOW", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CANCEL_ALL;   /* tcam and hash both have*/
    /*if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n",     "CANCEL_ALL");
    }*/

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DENY_BRIDGE;    /*only hash have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n",     "DENY_BRIDGE");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DENY_LEARNING;    /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n",     "DENY_LEARNING");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DENY_ROUTE;    /*only hash have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s \n",     "DENY_ROUTE");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DEST_CID;     /*only hash have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "DEST_CID", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DISABLE_ECMP_RR;        /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s\n", field_action.data0? "Ecmp rr mode: disable": "Ecmp rr mode: enable");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DISABLE_ECMP_DLB;        /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s\n", field_action.data0? "Ecmp dlb mode: disable": "Ecmp dlb mode: enable");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DISABLE_LINKAGG_RR;         /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s\n", field_action.data0? "Linkagg rr mode: disable": "Linkagg rr mode: enable");
    }
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_LB_HASH_ECMP_PROFILE;         /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-32s : %u\n", "Load balance hash ecmp profile id", field_action.data0? field_action.data1: 0);
    }
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_LB_HASH_LAG_PROFILE;         /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-32s : %u\n", "Load balance hash lag profile id", field_action.data0? field_action.data1: 0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CANCEL_ACL_TCAM_EN;    /*only hash have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        if(field_action.data1 == 1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: 0x%x\n", "CANCEL_ACL_TCAM_EN", field_action.data0);
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "CANCEL_ACL_TCAM_EN", field_action.data0);
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_REFLECTIVE_BRIDGE_EN;         /* only tcam  have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s: %d \n", "Reflective Bridge Enable", field_action.data0? 1: 0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_PORT_ISOLATION_DIS;         /* only tcam  have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s: %d \n", "Port Isolation Disable", field_action.data0? 1: 0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_EXT_TIMESTAMP;         /* only tcam  have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s: %d \n", "Ext Timestamp Enable", field_action.data0? 1: 0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DOT1AE_CHAN_ID;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "DOT1AE SC INDEX", field_action.data0);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "DOT1AE CLEAR TAG TYPE", field_action.data1);
    }
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_ECN;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "ecn", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DOT1AE_SPI;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "DOT1AE SPI", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CUT_THROUGH;         /* only tcam  have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s\n", "Cut Through Enable");
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_NSH;      /* tcam and hash both have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "NSH Bus Offset", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %d\n", "IPFIX Hash salt", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_QDROP_MONITOR;      /* only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "Queue Drop Monitor Enable", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_DSCP;      /* tcam and hash both have*/
    if (DRV_FROM_TMM(lchip) && (pe->action_type == SYS_ACL_ACTION_TCAM_INGRESS))
    {
        color_index = 0;
        SYS_ACL_SHOW_AD_WITH_COLOR(lchip, pe->fpae.entry_id, field_action, "DSCP", field_action.data0, SYS_ACL_SHOW_SUB_STR(color, color_index, field_action.data1, "", FALSE, (field_action.data1 != 0xff)));
    }
    else
    {
        if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "DSCP", field_action.data0);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_PRIORITY;    /* only tcam have*/
    {
        color_index = 0;
        SYS_ACL_SHOW_AD_WITH_COLOR(lchip, pe->fpae.entry_id, field_action, "PRIORITY", field_action.data0, SYS_ACL_SHOW_SUB_STR(color, color_index, field_action.data1, "", FALSE, (field_action.data1!=0xFFFFFFFF)));
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_IFA;    /*only tcam have*/
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "IFA Session ID", field_action.data0);
    }

    /* ext data */
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_XDATA;   /* tcam */
    field_action.ext_data = &xdata;
    xdata.type = (pe->action_type == SYS_ACL_ACTION_HASH_INGRESS)? CTC_XDATA_PROF_TYPE_DSFLOW:
        (pe->group->group_info.dir ? CTC_XDATA_PROF_TYPE_EGS_DSACL : CTC_XDATA_PROF_TYPE_DSACL);
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action) && xdata.num)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s\n", "Xdata");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "Profile Id", xdata.prof_id);
        for(loop=0;loop<xdata.num;loop++)
        {
            p_field = xdata.fields+loop;
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %24s%u: %u %s: %u %s: %s%u\n", 
            "Offset", loop, p_field->offset, "Width", p_field->width, "Value", 
            CTC_FLAG_ISSET(p_field->flag, CTC_XDATA_FIELD_FLAG_UDF) ? "UDF":"", p_field->data);
        }
    }
    
    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_CP_TO_CPU;   /* tcam and hash both have*/
    field_action.ext_data = &copy_to_cpu;
    if (DRV_FROM_TMM(lchip) && (pe->action_type == SYS_ACL_ACTION_TCAM_INGRESS))
    {
        color_index = 0;
        SYS_ACL_SHOW_AD_WITH_COLOR(lchip, pe->fpae.entry_id, field_action, "COPY TO CPU", copy_to_cpu.color, SYS_ACL_SHOW_CP_TO_CPU_REASON(copy_to_cpu, color, color_index, (copy_to_cpu.mode != CTC_ACL_TO_CPU_MODE_MAX)));
    }
    else
    {
        if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s:", "COPY TO CPU");
            color_index = 3;
            SYS_ACL_SHOW_CP_TO_CPU_REASON(copy_to_cpu, color, color_index, TRUE);
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_IPFIX;                /* only tcam have*/
    field_action.ext_data = &ipfix;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action) && field_action.data1)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: \n",  "Enable Ipfix");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "flow_cfg_id", ipfix.flow_cfg_id);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "field_sel_id", ipfix.field_sel_id);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "hash_type", ipfix.hash_type);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "use_mapped_vlan", ipfix.use_mapped_vlan);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "use_cvlan", ipfix.use_cvlan);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "policer_id", ipfix.policer_id);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "lantency_en", ipfix.lantency_en);
        if(DRV_FROM_AT(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "sudf_en", ipfix.sudf_en);
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "flex_key_en", ipfix.flex_key_en);
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "cancel_learning", ipfix.cancel_learning);
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_OAM;                     /* only tcam have*/
    field_action.ext_data = &oam;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action) )
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: \n",  "Enable OAM");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "dest_gchip", oam.dest_gchip);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "lmep_index", oam.lmep_index);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "mip_en", oam.mip_en);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "oam_type", oam.oam_type);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "link_oam_en", oam.link_oam_en);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "packet_offset", oam.packet_offset);
        if (DRV_FLD_IS_EXISIT(DsAcl_t, DsAcl_u1_g3_macDaChkEn_f))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "mac_da_check_en", oam.mac_da_check_en);
        }
        if (DRV_FLD_IS_EXISIT(DsAcl_t, DsAcl_u1_g3_selfAddress_f))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "is_self_address", oam.is_self_address);
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "time_stamp_en", oam.time_stamp_en);
        if (DRV_FLD_IS_EXISIT(DsAcl_t, DsAcl_u1_g3_twampTsType_f))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "timestamp_format", oam.timestamp_format);
        }
        if (DRV_FLD_IS_EXISIT(DsAcl_t, DsAcl_u1_g3_twampIsAck_f))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "twamp_reflect_en", oam.twamp_reflect_en ? 0 : 1);
        }
        if (DRV_FLD_IS_EXISIT(DsAcl_t, DsAcl_u1_g3_galExist_f))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "gal_exist", oam.gal_exist);
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH;      /* tcam and hash both have*/
    field_action.ext_data = &lb_hash;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s:%d(mode:%d) \n", "REPLACE_LB_HASH",lb_hash.lb_hash,lb_hash.mode);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_INTER_CN;     /* only tcam have*/
    field_action.ext_data = &inter_cn;
    if (DRV_FROM_TMM(lchip) && (pe->action_type == SYS_ACL_ACTION_TCAM_INGRESS))
    {
        color_index = 0;
        SYS_ACL_SHOW_AD_WITH_COLOR(lchip, pe->fpae.entry_id, field_action, "INTER_CN", inter_cn.color, SYS_ACL_SHOW_SUB_STR(color, color_index, inter_cn.inter_cn, "", FALSE, field_action.data1));
    }
    else
    {
        if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "INTER_CN", inter_cn.inter_cn);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_VLAN_EDIT;   /* only tcam have*/
    field_action.ext_data = &vlan_edit;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s:%s\n", "VLAN_EDIT", (vlan_edit.stag_op == CTC_VLAN_TAG_OP_NONE && vlan_edit.ctag_op == CTC_VLAN_TAG_OP_NONE) ? "None":"");
        if (vlan_edit.stag_op != CTC_VLAN_TAG_OP_NONE)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s - %s\n", "Stag_op", _sys_usw_get_vlan_edit_desc(1, vlan_edit.stag_op));
            if (vlan_edit.stag_op != CTC_VLAN_TAG_OP_DEL)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %28s - %-12s  %s - %u\n", "svid_sl", _sys_usw_get_vlan_edit_desc(0, vlan_edit.svid_sl), "New_svid", vlan_edit.svid_new);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %28s - %-12s  %s - %u\n", "scos_sl", _sys_usw_get_vlan_edit_desc(0, vlan_edit.scos_sl), "New_scos", vlan_edit.scos_new);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %28s - %-12s  %s - %u\n", "scfi_sl", _sys_usw_get_vlan_edit_desc(0, vlan_edit.scfi_sl), "New_scfi", vlan_edit.scfi_new);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %28s - %-12u\n", "tpid_idx", vlan_edit.tpid_index);
            }
        }
        if (vlan_edit.ctag_op != CTC_VLAN_TAG_OP_NONE)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s - %s\n", "Ctag_op", _sys_usw_get_vlan_edit_desc(1, vlan_edit.ctag_op));
            if (vlan_edit.ctag_op != CTC_VLAN_TAG_OP_DEL)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %28s - %-12s  %s - %u\n", "cvid_sl", _sys_usw_get_vlan_edit_desc(0, vlan_edit.cvid_sl), "New_cvid", vlan_edit.cvid_new);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %28s - %-12s  %s - %u\n", "ccos_sl", _sys_usw_get_vlan_edit_desc(0, vlan_edit.ccos_sl), "New_ccos", vlan_edit.ccos_new);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %28s - %-12s  %s - %u\n", "ccfi_sl", _sys_usw_get_vlan_edit_desc(0, vlan_edit.ccfi_sl), "New_ccfi", vlan_edit.ccfi_new);
            }
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_STRIP_PACKET;   /* only tcam have*/
    field_action.ext_data = &strip_pkt;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: \n",  "STRIP_PACKET");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "start_packet_strip", strip_pkt.start_packet_strip);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "packet_type", strip_pkt.packet_type);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "strip_extra_len", strip_pkt.strip_extra_len);
        if (0 != strip_pkt.srv6_edit_en)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "srv6_edit_en", strip_pkt.srv6_edit_en);
        }
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_QOS_TABLE_MAP;   /* only tcam have*/
    field_action.ext_data = &table_map;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        CTC_ERROR_RETURN(_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action));
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: \n",     "QOS_TABLE_MAP");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "table_map_id", table_map.table_map_id);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %25s: %u\n", "table_map_type", table_map.table_map_type);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_VXLAN_RSV_EDIT;         /* only tcam have*/
    field_action.ext_data = (void*)&vxlan_rsv_edit;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s : %d\n", "Vxlan reserved edit mode", vxlan_rsv_edit.edit_mode);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s : 0x%x\n", "Vxlan flags", vxlan_rsv_edit.vxlan_flags);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s : 0x%x\n", "Vxlan reserved1", vxlan_rsv_edit.vxlan_rsv1);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s : 0x%x\n", "Vxlan reserved2", vxlan_rsv_edit.vxlan_rsv2);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_TIMESTAMP;         /* only tcam  have*/
    field_action.ext_data = (void*)&timestamp;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-24s: %d \n", "Timestamp Mode", timestamp.mode);
    }

    sal_memset(&field_action,0, sizeof(ctc_acl_field_action_t));
    field_action.type = CTC_ACL_FIELD_ACTION_INT;    /*only tcam have*/
    field_action.ext_data = (void*)&acl_int;
    if(!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &field_action))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "INT Session Type", acl_int.session_type);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: %u\n", "INT Session ID", acl_int.session_id);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  %-16s: 0x%-4X\n", "INT Instruction Bitmap", acl_int.instruction_bitmap);
    }

    return CTC_E_NONE;
}

#if 0
 /* 1: layer3HeaderProtocol*/
 /* 2: layer4Type*/
int32
_sys_usw_acl_l4type_ipprotocol_judge(uint8 lchip, uint8 key_type, uint8 hash_sel_id)
{
    ds_t ds_sel ={0};
    if (CTC_ACL_KEY_HASH_IPV4 == key_type || CTC_ACL_KEY_HASH_IPV6 == key_type)
    {
        if (CTC_ACL_KEY_HASH_IPV4 == key_type )
        {
            CTC_ERROR_RETURN(_sys_usw_acl_get_field_sel(lchip, CTC_ACL_KEY_HASH_IPV4, hash_sel_id, &ds_sel));
            if (GetFlowL3Ipv4HashFieldSelect(V, layer3HeaderProtocolEn_f, &ds_sel))
            {
                return 1;
            }
            else
            {
                return 2;
            }
        }
        else  /* DsFlowL2HashKey  DsAclQosL3Key160 DsAclQosL3Key320	DsAclQosMacL3Key320  DsAclQosMacL3Key640  DsAclQosForwardKey320  DsAclQosForwardKey640  DsAclQosCoppKey320  DsAclQosCoppKey640*/
        {
            CTC_ERROR_RETURN(_sys_usw_acl_get_field_sel(lchip, CTC_ACL_KEY_HASH_IPV6, hash_sel_id, &ds_sel));
            if (GetFlowL3Ipv6HashFieldSelect(V, layer3HeaderProtocolEn_f, &ds_sel))
            {
                return 1;
            }
            else
            {
                return 2;
            }
        }
    }
    else if(CTC_ACL_KEY_IPV4 == key_type || CTC_ACL_KEY_CID == key_type || CTC_ACL_KEY_INTERFACE == key_type || CTC_ACL_KEY_FWD == key_type)
    {
        return 2;
    }
    else
    {
        return 1;
    }

}
#endif

STATIC int32
 _sys_usw_acl_filter_by_key(uint8 lchip, sys_acl_entry_t* pe, ctc_field_key_t* p_grep, uint8 grep_cnt,uint32 key_id)
{
    ctc_field_key_t field_key;
    uint8 data_temp[SYS_USW_ACL_MAX_KEY_SIZE] = {0};
    uint8 mask_temp[SYS_USW_ACL_MAX_KEY_SIZE] = {0};
    uint8 result_grep_temp[SYS_USW_ACL_MAX_KEY_SIZE] = {0};
    uint8 result_data_temp[SYS_USW_ACL_MAX_KEY_SIZE] = {0};
    uint32 result_grep = 0;
    uint32 result_data = 0;
    uint8  grep_i = 0;
    char* print_str = NULL;
    uint32 key_size = 0;

    CTC_PTR_VALID_CHECK(pe);
    CTC_PTR_VALID_CHECK(p_grep);

    sal_memset(&field_key,0, sizeof(ctc_field_key_t));
    field_key.ext_data = data_temp;
    field_key.ext_mask = mask_temp;

    for(grep_i = 0;grep_i< grep_cnt; grep_i++)
    {
        sal_memset(data_temp,0,sizeof(data_temp));
        sal_memset(mask_temp,0,sizeof(mask_temp));

        if ((p_grep[grep_i].type == CTC_FIELD_KEY_ETHER_TYPE) && (CTC_ACL_KEY_MAC != pe->key_type))
        {
            uint8  l3_type = CTC_PARSER_L3_TYPE_NONE;
            _sys_usw_acl_map_ethertype(p_grep[grep_i].data, &l3_type);
            if (l3_type != CTC_PARSER_L3_TYPE_NONE)
            {
                p_grep[grep_i].type = CTC_FIELD_KEY_L3_TYPE;
                p_grep[grep_i].data = l3_type;
            }
        }

        if (SYS_ACL_GROUP_IS_PRESEL(pe->group)&& ACL_ENTRY_IS_TCAM(pe))
        {
            uint32 key_width = 0;

            field_key.type = p_grep[grep_i].type;
            if (1 == MCHIP_ACL(lchip)->get_key_field(lchip, pe,  &field_key, &key_width))
            {   /* initial conditions */
                return CTC_E_INVALID_PARAM;    /* grep fail */
            }

            key_size =  (key_width + 7) / 8;
        }
        else
        {
            if (1 == _sys_usw_acl_get_key_field_value(lchip, pe, p_grep[grep_i].type, key_id, &field_key, &print_str, &key_size))
            {   /* initial conditions */
                return CTC_E_INVALID_PARAM;    /* grep fail */
            }
        }

        /*special process for discard use data & ext_data*/
        if(CTC_FIELD_KEY_DISCARD == p_grep[grep_i].type)
        {
            uint8 discard_data = 0;
            uint8 discard_mask = 0;
            if(p_grep[grep_i].ext_data)
            {
                discard_data = *(uint32*)p_grep[grep_i].ext_data;
                discard_mask = 0x3F;
            }
            p_grep[grep_i].data = p_grep[grep_i].data<<6|(discard_data & 0x3F);
            p_grep[grep_i].mask = p_grep[grep_i].mask<<6|(discard_mask & 0x3F);
        }
        if(ACL_ENTRY_IS_TCAM(pe))
        {
            if (p_grep[grep_i].ext_data && p_grep[grep_i].ext_mask)
            {
                uint32 loop;
                for(loop=0; loop < key_size; loop++)
                {
                    result_grep_temp[loop] = (*((uint8*)p_grep[grep_i].ext_data+loop)) & (*((uint8*)p_grep[grep_i].ext_mask+loop));
                    result_data_temp[loop] = (*((uint8*)field_key.ext_data+loop)) & (*((uint8*)field_key.ext_mask+loop));
                }

                if(0 != sal_memcmp(result_grep_temp, result_data_temp, key_size))
                {
                    return CTC_E_INVALID_PARAM;  /* grep fail */
                }
                sal_memset(result_grep_temp,0,sizeof(result_grep_temp));
                sal_memset(result_data_temp,0,sizeof(result_data_temp));
            }
            else
            {
                result_grep = p_grep[grep_i].data & p_grep[grep_i].mask;
                result_data = field_key.data  & field_key.mask & p_grep[grep_i].mask;
                if(result_grep != result_data)
                {
                    return CTC_E_INVALID_PARAM; /* grep fail */
                }
                result_grep = 0;
                result_data = 0;
            }
        }
        else
        {
            if (p_grep[grep_i].ext_data)
            {
                if(0 != sal_memcmp(p_grep[grep_i].ext_data, field_key.ext_data, key_size))
                {
                    return CTC_E_INVALID_PARAM; /* grep fail */
                }
            }
            else
            {
                if(p_grep[grep_i].data != field_key.data)
                {
                    return CTC_E_INVALID_PARAM; /* grep fail */
                }
            }
        }
    }
    return CTC_E_NONE;
}

int32
sys_usw_acl_get_aset(uint8 lchip, uint8 type, uint32 parm, ctc_acl_aset_t* o_aset)
{
    int32 ret = CTC_E_NONE;
    uint16 aset_id = 0;
    uint8 action_type = 0xff;
    sys_acl_aset_t* p_aset = NULL;

    SYS_ACL_INIT_CHECK();
    CTC_PTR_VALID_CHECK(o_aset);
    SYS_USW_ACL_LOCK(lchip);
    if(type == 1)
    {
        sys_acl_entry_t * pe;
        _sys_usw_acl_get_entry_by_eid(lchip, parm, &pe);
        if(!pe)
        {
            ret = CTC_E_ENTRY_NOT_EXIST;
            goto done;
        }
        aset_id = pe->aset_id;
        action_type = pe->action_type;
    }
    else if (type == 2)
    {
        sys_acl_group_t* pg;
        _sys_usw_acl_get_group_by_gid(lchip, parm, &pg);
        if(!pg)
        {
            ret = CTC_E_ENTRY_NOT_EXIST;
            goto done;
        }
        aset_id = pg->aset_id;
        action_type = (pg->group_info.type == CTC_ACL_GROUP_TYPE_HASH) ? SYS_ACL_ACTION_HASH_INGRESS :
            (CTC_INGRESS == pg->group_info.dir ? SYS_ACL_ACTION_TCAM_INGRESS : SYS_ACL_ACTION_TCAM_EGRESS);
    }
    else if(type == 3)
    {
        aset_id = parm;
    }
    else
    {
        ret = CTC_E_INVALID_PARAM;
        goto done;
    }

    ret = _sys_usw_acl_get_aset(lchip, aset_id, &p_aset);
    if(ret == 0)
    {
        o_aset->aset_id = p_aset->aset_id;
        sal_memcpy(o_aset->w, p_aset->w, sizeof(p_aset->w));
        o_aset->type = (action_type == 0xff )? p_aset->type : action_type;
    }

done:
    SYS_USW_ACL_UNLOCK(lchip);
    return ret;
}

/*
 * show acl entry to a specific entry with specific key type
 */
STATIC int32
_sys_usw_acl_show_entry(uint8 lchip,
                        sys_acl_entry_t* pe,
                        uint32* p_cnt,
                        uint16 key_type,
                        uint8 detail,
                        uint8 show_type,
                        ctc_field_key_t* p_grep,
                        uint8 grep_cnt,
                        uint8 show_inner)
{
    int32  ret = CTC_E_NONE;
    char*  type[32];
    char* type_new[] = {"Tcam-Mac", "Tcam-Ipv4", "Tcam-Mpls", "Tcam-Ipv6", "Hash-Mac",
                        "Hash-Ipv4", "Hash-L2-L3", "Hash-Mpls", "Hash-Ipv6", "Hash-Nsh", "Tcam-Pbr-Ipv4",
                        "Tcam-Pbr-Ipv6", "Tcam-Ipv4-Ext", "Tcam-Mac-Ipv4", "Tcam-Mac-Ipv4-Ext",
                        "Tcam-Ipv6-Ext", "Tcam-Mac-Ipv6", "Tcam-Cid", "Tcam-Interface",
                        "Tcam-Fwd", "Tcam-Fwd-Ext", "Tcam-Copp", "Tcam-Copp-Ext", "Tcam-Udf", "Tcam-Stk-Hdr"};

    char* type_old[] = {"TcamMac-160", "TcamL3-160", "Tcam-Mpls", "TcamIpv6-320", "Hash-Mac",
                        "Hash-Ipv4", "Hash-L2-L3", "Hash-Mpls", "Hash-Ipv6", "Hash-Nsh", "Tcam-pbr-ipv4",
                        "Tcam-pbr-ipv6", "TcamL3-320", "TcamMacL3-320", "TcamMacL3-640",
                        "TcamIpv6-640", "TcamMacIpv6-640", "TcamCID-160", "TcamInterface-80",
                        "TcamFwd-320", "TcamFwd-640", "TcamCopp-320", "TcamCopp-640", "TcamUDF-320"};
    sys_acl_group_t* pg;
    char    str[35]     = {0};
    char    format[10]  = {0};
    uint32  key_id       = 0;
    uint32  act_id       = 0;
    uint32  hw_index     = 0;
    uint32  priority     = 0;
    char    key_name[50] = {0};
    char    ad_name[50]  = {0};
    char    flex_type[14] = "";
    uint8 part = 0;
    uint8 part_num = 0;
    uint8 step = 0;
    uint16 tmp_key_type = pe->key_type;
    sys_acl_flex_key_t* fk = NULL;
    ctc_acl_field_action_t action;
    uint8 is_discard = 0;
    uint8 is_cancel_dis = 0;
    uint8 is_redirect = 0;
    uint8 ad_type = 0;

    CTC_PTR_VALID_CHECK(pe);
    sal_memset(&action, 0, sizeof(action));
    if(DRV_FROM_TMM(lchip))
    {
        sal_memcpy(type, type_new, sizeof(type_new));
    }
    else
    {
        sal_memcpy(type, type_old, sizeof(type_old));
    }
    pg = pe->group;
    if (!pg)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Acl] Group not exist \n");
        return CTC_E_NOT_EXIST;
    }

    if ((CTC_ACL_KEY_NUM != key_type)
        && (pe->key_type != key_type))
    {
        return CTC_E_NONE;
    }

    ad_type = ACL_ENTRY_IS_TCAM(pe) ? pe->ad_type : 0;
    SYS_ACL_GET_TBL_FUNC(lchip, pe, &key_id, &act_id, &hw_index);
    if (ACL_ENTRY_IS_INSTALLED(pe))
    {
        CTC_ERROR_RETURN(_sys_usw_acl_rebuild_buffer_from_hw(lchip, key_id, act_id, hw_index, pe));
    }
    if (ACL_ENTRY_IS_TCAM(pe) && SYS_ACL_GROUP_IS_PRESEL(pg))
    {
        SYS_ACL_KEY_SIZE_TO_STEP(pe->fpae.key_size, step);
        act_id = act_id - step;
    }

    fk = pe->ua->buffer.fk;
    if (SYS_ACL_GROUP_IS_PRESEL(pg) && ACL_ENTRY_IS_TCAM(pe))
    {
        SYS_ACL_KEY_SIZE_TO_PART_NUM(fk->key_size, part_num);
    }

    if (0 != grep_cnt)
    {
        if (_sys_usw_acl_filter_by_key(lchip, pe, p_grep, grep_cnt, key_id) != CTC_E_NONE)
        {
            ret = CTC_E_NONE;
            goto clean_up;
        }
    }

    if ((!detail) || (1 == show_type))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-8d", *p_cnt);
        if(SYS_ACL_SHOW_IN_HEX <= pe->fpae.entry_id)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s", CTC_DEBUG_HEX_FORMAT(str, format, pe->fpae.entry_id, 8, U));
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", pe->fpae.entry_id);
        }

        if (SYS_ACL_SHOW_IN_HEX <= pg->group_id)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s", CTC_DEBUG_HEX_FORMAT(str, format, pg->group_id, 8, U));
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", pg->group_id);
        }

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-4s", ACL_ENTRY_IS_INSTALLED(pe) ? "Y" : "N");
        priority = ACL_ENTRY_IS_TCAM(pe)?pe->fpae.priority : fk ? ACL_SHARE_PTR(pe, sys_acl_hash_entry_t)->priority : 1;
        if(SYS_ACL_SHOW_IN_HEX <= priority)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s", CTC_DEBUG_HEX_FORMAT(str, format, priority, 8, U));
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", priority);
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-8u", pg->group_info.block_id);

        if (SYS_ACL_KEY_IS_FLEX(tmp_key_type))
        {
            sal_sprintf(flex_type, (SYS_ACL_FK_IS_HASH(fk) ? "Hash-Flex-%d" : "Tcam-Flex-%d"), pe->key_type);
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-18s", flex_type);
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-18s", type[pe->key_type]);
        }

        SYS_ACL_GET_TBL_FUNC(lchip, pe, &key_id, &act_id, &hw_index);

        if (ACL_ENTRY_IS_TCAM(pe))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-8u",  hw_index/pe->fpae.real_step);
        }
        else   /*hash*/
        {
            if (ACL_SHARE_PTR(pe,sys_acl_hash_entry_t)->key_exist)   /*hash key index is not avaliable*/
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8s ", "keyExist");
            }
            else if(ACL_SHARE_PTR(pe,sys_acl_hash_entry_t)->key_conflict)   /*hash key index is not avaliable*/
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8s ", "bucketFull");
            }
            else if(!ACL_SHARE_PTR(pe,sys_acl_hash_entry_t)->hash_valid)   /*hash key index is not avaliable*/
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8s ", "keyIncomplete");
            }
            else
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8s",  CTC_DEBUG_HEX_FORMAT(str, format, hw_index, 4, U));
            }
        }

        action.type = CTC_ACL_FIELD_ACTION_DISCARD;
        if (!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &action))
        {
            is_discard = action.data1;
        }
        action.type = CTC_ACL_FIELD_ACTION_CANCEL_DISCARD;
        if (!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &action))
        {
            is_cancel_dis = action.data1;
        }
        action.type = CTC_ACL_FIELD_ACTION_REDIRECT;
        if (!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &action))
        {
            is_redirect = 1;
        }
        else
        {
            action.type = CTC_ACL_FIELD_ACTION_REDIRECT_PORT;
            if (!_sys_usw_acl_get_action_field(lchip, pe->fpae.entry_id, &action))
            {
                is_redirect = 1;
            }
        }

        if(is_discard && is_cancel_dis)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10s", "CLR-based");
        }
        else if(is_discard)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10s", "Discard");
        }
        else if(is_redirect)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10s", "Redirect");
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10s", "Permit");
        }

        if (ACL_ENTRY_IS_TCAM(pe) && SYS_ACL_GROUP_IS_PRESEL(pg))
        {
            SYS_ACL_KEY_SIZE_TO_STEP(pe->fpae.key_size, step);
            act_id = act_id - step;
            switch(fk->key_size)
            {
            case CTC_FPA_KEY_SIZE_160:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "160");
                break;
            case CTC_FPA_KEY_SIZE_320:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "320");
                break;
            case CTC_FPA_KEY_SIZE_640:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "480");
                break;
            default:
                break;
            }
        }
        else
        {
            switch(pe->key_type)
            {
            case CTC_ACL_KEY_INTERFACE:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "80");
                break;
            case CTC_ACL_KEY_MAC:
            case CTC_ACL_KEY_IPV4:
            case CTC_ACL_KEY_HASH_MAC:
            case CTC_ACL_KEY_HASH_IPV4:
            case CTC_ACL_KEY_HASH_MPLS:
            case CTC_ACL_KEY_HASH_NSH:
            case CTC_ACL_KEY_PBR_IPV4:
            case CTC_ACL_KEY_CID:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "160");
                break;
            case CTC_ACL_KEY_MPLS:
            case CTC_ACL_KEY_IPV6:
            case CTC_ACL_KEY_HASH_L2_L3:
            case CTC_ACL_KEY_HASH_IPV6:
            case CTC_ACL_KEY_PBR_IPV6:
            case CTC_ACL_KEY_IPV4_EXT:
            case CTC_ACL_KEY_MAC_IPV4:
            case CTC_ACL_KEY_FWD:
            case CTC_ACL_KEY_COPP:
            case CTC_ACL_KEY_UDF:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "320");
                break;
            case CTC_ACL_KEY_MAC_IPV4_EXT:
            case CTC_ACL_KEY_IPV6_EXT:
            case CTC_ACL_KEY_MAC_IPV6:
            case CTC_ACL_KEY_FWD_EXT:
            case CTC_ACL_KEY_COPP_EXT:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "640");
                break;
            default:
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s", "---");
                break;
            }
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        (*p_cnt)++;
    }

    if(detail)
    {
        drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, key_id, 0, key_name);

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");

        if(SYS_ACL_SHOW_IN_HEX <= pe->fpae.entry_id)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#ENTRY_ID: %-12s", CTC_DEBUG_HEX_FORMAT(str, format, pe->fpae.entry_id, 8, U));
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#ENTRY_ID: %-12u", pe->fpae.entry_id);
        }
        if (ACL_ENTRY_IS_TCAM(pe))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Ad_type: %-2d\n", ad_type);
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Ad_type: %-2s\n", "-");
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Table:\n");

        drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, act_id, 0, ad_name);
        if (!ACL_ENTRY_IS_TCAM(pe))   /*hash*/
        {
            if(0XFFFFFF == ACL_SHARE_PTR(pe,sys_acl_hash_entry_t)->key_index)   /*hash key index is not avaliable*/
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," --%-32s :%-8s\n", key_name, "Invalid");
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," --%-32s :%-8s\n", ad_name, "Invalid");
            }
            else
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," --%-32s :0x%-8x\n", key_name, hw_index);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," --%-32s :0x%-8x\n", ad_name, (key_id == act_id ? hw_index : pe->ua->buffer.ad.hash.ad_index));
            }
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," --%-32s :%-8u\n", key_name, SYS_ACL_MAP_DRV_KEY_INDEX(hw_index, pe->fpae.real_step));
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," --%-32s :%-8u\n", ad_name, SYS_ACL_MAP_DRV_AD_INDEX(hw_index, pe->fpae.real_step));


            if (SYS_ACL_GROUP_IS_PRESEL(pg))
            {
                for (part = 1; part < part_num; part++)
                {
                    drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, key_id + part, 0, key_name);
                    drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, act_id + part, 0, ad_name);

                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%-8u\n", key_name, SYS_ACL_MAP_DRV_KEY_INDEX(hw_index, pe->fpae.real_step));
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%-8u\n", ad_name, SYS_ACL_MAP_DRV_AD_INDEX(hw_index, pe->fpae.real_step));
                }
            }

        }

        if (SYS_ACL_GROUP_IS_PRESEL(pg) && ACL_ENTRY_IS_TCAM(pe) && MCHIP_ACL(lchip)->show_key_field)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nKey:\n");
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-------------------------------------\n");

            CTC_ERROR_GOTO(MCHIP_ACL(lchip)->show_key_field(lchip, pe, show_inner), ret, clean_up);
        }
        else
        {
            CTC_ERROR_GOTO(_sys_usw_acl_show_key(lchip, pe, key_id, p_grep, grep_cnt), ret, clean_up);
        }

       _sys_usw_acl_show_action(lchip, pe);

    }
clean_up:
    if (ACL_ENTRY_IS_INSTALLED(pe))
    {
        if (ACL_ENTRY_IS_TCAM(pe))
        {
            _sys_usw_acl_map_action_data(lchip, pe, TRUE);
        }
        sys_usw_acl_buffer_malloc(lchip, pe, FALSE);
    }
    return ret;
}

STATIC int32
_sys_usw_acl_show_entry_by_type(uint8 lchip,
                                uint16 key_type,
                                void* pe,
                                void* p_cnt,
                                uint8 detail,
                                uint8 show_type,
                                void* p_grep,
                                uint8 grep_cnt,
                                uint8 show_inner)
{
    if(CTC_ACL_KEY_IPV4 == key_type)
    {
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV4, detail, show_type, p_grep, grep_cnt, show_inner));
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV4_EXT, detail,show_type, p_grep, grep_cnt, show_inner));
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_MAC_IPV4, detail,show_type, p_grep, grep_cnt, show_inner));
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_MAC_IPV4_EXT, detail,show_type, p_grep, grep_cnt, show_inner));
    }
    else if(CTC_ACL_KEY_IPV6 == key_type)
    {
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV6, detail,show_type, p_grep, grep_cnt, show_inner));
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV6_EXT, detail,show_type, p_grep, grep_cnt, show_inner));
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_MAC_IPV6, detail,show_type, p_grep, grep_cnt, show_inner));
    }
    else if(CTC_ACL_KEY_FWD == key_type)
    {
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_FWD, detail,show_type, p_grep, grep_cnt, show_inner));
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_FWD_EXT, detail,show_type, p_grep, grep_cnt, show_inner));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, key_type, detail,show_type, p_grep, grep_cnt, show_inner));
    }
    return CTC_E_NONE;
}

/*
 * show acl entriy by entry id
 */
int32
_sys_usw_acl_show_entry_by_entry_id(uint8 lchip,
                                    uint32 eid,
                                    uint16 key_type,
                                    uint8 detail,
                                    uint8 show_type,
                                    ctc_field_key_t* p_grep,
                                    uint8 grep_cnt,
                                    uint8 show_inner)
{
    sys_acl_entry_t* pe = NULL;

    uint32         count = 1;

    _sys_usw_acl_get_entry_by_eid(lchip, eid, &pe);
    if (!pe)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Acl] Entry not exist \n");
            return CTC_E_NOT_EXIST;

    }
    CTC_ERROR_RETURN(_sys_usw_acl_show_entry_by_type(lchip, key_type, &pe->fpae, &count, detail, show_type, p_grep, grep_cnt, show_inner));
    return CTC_E_NONE;
}

/*
 * show acl entries in a group with specific key type
 */
STATIC int32
_sys_usw_acl_show_entry_in_group(uint8 lchip, sys_acl_group_t* pg,_acl_cb_para_t* cb_para)
{
    ctc_list_pointer_node_t* pe;

	uint16 key_type = cb_para->key_type;
    uint8 detail = cb_para->detail;
	uint8 loop_en = 0;
	uint8 is_tcam = (cb_para->entry_type == 0) || (cb_para->entry_type ==2);
    uint8 is_hash = (cb_para->entry_type == 1) || (cb_para->entry_type ==2);
    uint8 show_inner = cb_para->show_inner;

    CTC_PTR_VALID_CHECK(pg);
    CTC_LIST_POINTER_LOOP(pe, &(pg->entry_list))
    {
        loop_en =  (ACL_ENTRY_IS_TCAM(((sys_acl_entry_t *) pe)) && is_tcam) \
		        || (!ACL_ENTRY_IS_TCAM(((sys_acl_entry_t *) pe)) && is_hash);
	    if(!loop_en)
		{
		   continue;
		}
        CTC_ERROR_DUMP(_sys_usw_acl_show_entry_by_type(lchip, key_type, &(((sys_acl_entry_t*)pe)->fpae), &cb_para->count, detail, cb_para->show_type, cb_para->p_grep, cb_para->grep_cnt, show_inner));
    }

    return CTC_E_NONE;
}

/*
 * show acl entries by group id with specific key type
 */
int32
_sys_usw_acl_show_entry_by_group_id(uint8 lchip,
                                    uint32 gid,
                                    uint16 key_type,
                                    uint8 detail,
                                    uint8 show_type,
                                    ctc_field_key_t* p_grep,
                                    uint8 grep_cnt,
                                    uint8 show_inner)
{
    sys_acl_group_t* pg  = NULL;
	_acl_cb_para_t cb_para;
	cb_para.count = 1;
	cb_para.entry_type = 2;
	cb_para.key_type = key_type;
    cb_para.show_type = show_type;
	cb_para.grep_cnt = grep_cnt;
	cb_para.p_grep = p_grep;
    cb_para.show_inner = show_inner;

    _sys_usw_acl_get_group_by_gid(lchip, gid, &pg);
    SYS_ACL_CHECK_GROUP_UNEXIST(pg);

	cb_para.detail = 0;
    CTC_ERROR_RETURN(_sys_usw_acl_show_entry_in_group(lchip, pg, &cb_para));
    if(detail)
    {
        cb_para.detail = 1;
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry_in_group(lchip, pg, &cb_para));
    }

    return CTC_E_NONE;
}

/*
 * show acl entries in a block with specific key type
 */
STATIC int32
_sys_usw_acl_show_entry_in_block(   uint8 lchip,
                                    sys_acl_block_t* pb,
                                    uint32* p_cnt,
                                    uint16 key_type,
                                    uint8 detail,
                                    uint8 show_type,
                                    ctc_field_key_t* p_grep,
                                    uint8 grep_cnt,
                                    uint8 show_inner)
{
    ctc_fpa_entry_t* pe = NULL;
    uint16         block_idx;
    uint8          step = 0;
    uint8          part_num = 0;

    CTC_PTR_VALID_CHECK(pb);
    CTC_PTR_VALID_CHECK(p_cnt);

    step  = 1;
    part_num = pb->fpab.same_size? pb->fpab.part_num: 1;

    if(pb[0].fpab.vblock)   /* explan block 160bit entry */
    {
        for (block_idx = 0; (block_idx<pb[0].fpab.vblock->entry_count); block_idx++)
        {
            pe = pb[0].fpab.vblock->entries[block_idx];
            if(!pe)
            {
                continue;
            }
            CTC_ERROR_RETURN(_sys_usw_acl_show_entry_by_type(lchip, key_type, pe, p_cnt, detail, show_type, p_grep, grep_cnt, show_inner));
        }
    }

    if(part_num != 1 && pb->fpab.same_size)
    {
        for (block_idx = 0; (block_idx<pb[0].fpab.entry_count); block_idx++)
        {
            pe = pb[0].fpab.entries[block_idx];
            if(!pe || pe->key_size <= 1) /* 160 bit entry in vblock*/
            {
                continue;
            }
            CTC_ERROR_RETURN(_sys_usw_acl_show_entry_by_type(lchip, key_type, pe, p_cnt, detail, show_type, p_grep, grep_cnt, show_inner));
        }
    }
    else
    {
        for (block_idx = 0; block_idx < pb->fpab.entry_count; block_idx = block_idx + step)
        {
            pe = pb->fpab.entries[block_idx];
            if(!pe)
            {
                continue;
            }
            if(pb->fpab.same_size)
            {
                step = 1;
            }
            else if((block_idx >= pb->fpab.start_offset[3]) && (pb->fpab.sub_entry_count[3]))        /*640 bit key*/
            {
                step = 8;
            }
            else if(block_idx >= pb->fpab.start_offset[2] && (pb->fpab.sub_entry_count[2]))   /*320 bit key*/
            {
                step = 4;
            }
            else if(block_idx >= pb->fpab.start_offset[1] && (pb->fpab.sub_entry_count[1]))   /*160 bit key*/
            {
                step = 2;
            }
            else                                            /*80 bit key*/
            {
                step = 1;
            }
            CTC_ERROR_RETURN(_sys_usw_acl_show_entry_by_type(lchip, key_type, pe, p_cnt, detail, show_type, p_grep, grep_cnt, show_inner));
        }
    }

    return CTC_E_NONE;
}

/*
 * show acl entries by group block
 */
int32
_sys_usw_acl_show_entry_by_priority(uint8 lchip,
                                    uint8 block_id,
                                    uint16 key_type,
                                    uint8 detail,
                                    uint8 show_type,
                                    ctc_field_key_t* p_grep,
                                    uint8 grep_cnt,
                                    uint8 show_inner)
{
    uint32         count = 1;
    sys_acl_block_t *pb = NULL;
    uint8 merge_size= 0 ;
    uint8 part= 0 ;
    uint8 bmp= 0 ;

    CTC_MAX_VALUE_CHECK(block_id, (p_usw_acl_master[lchip]->igs_block_num - 1));

    count = 1;
    pb = &SYS_ACL_BLOCK(lchip, block_id);
    merge_size = pb->fpab.part_num;
    for (part = 0; part < merge_size; part++)
    {
        bmp |= (pb[part].fpab.free_count != pb[part].fpab.entry_count && pb[part].fpab.part == part);
    }
    if (bmp && pb->fpab.part == 0) /*not empty*/
    {
        CTC_ERROR_RETURN(_sys_usw_acl_show_entry_in_block(lchip, pb, &count, key_type, detail,show_type, p_grep, grep_cnt, show_inner));
    }

    if(block_id < p_usw_acl_master[lchip]->egs_block_num)
    {
        pb = &SYS_ACL_BLOCK(lchip, block_id + p_usw_acl_master[lchip]->igs_block_num);
        merge_size = pb->fpab.part_num;
        for (part = 0; part < merge_size; part++)
        {
            bmp |= (pb[part].fpab.free_count != pb[part].fpab.entry_count && pb[part].fpab.part == part);
        }
        if (bmp && pb->fpab.part == 0) /*not empty*/
        {
            CTC_ERROR_RETURN(_sys_usw_acl_show_entry_in_block(lchip, pb, &count, key_type, detail,show_type, p_grep, grep_cnt, show_inner));
        }
    }
    return CTC_E_NONE;
}

/*
 * show acl entries in a block with specific key type
 */
STATIC int32
_sys_usw_acl_show_entry_in_lkup_level(  uint8 lchip,
                                        uint8 block_id,
                                        uint8 level,
                                        sys_acl_block_t* pb,
                                        uint32* p_cnt,
                                        uint16 key_type,
                                        uint8 detail,
                                        uint8 show_type,
                                        ctc_field_key_t* p_grep,
                                        uint8 grep_cnt,
                                        uint8 show_inner)
{
    ctc_fpa_entry_t* pe = NULL;
    uint16         block_idx = 0;
    uint16         start_idx = 0;
    uint16         end_idx = 0;
    uint8          step = 0;
    sys_acl_league_t*    p_sys_league = NULL;

    CTC_PTR_VALID_CHECK(pb);
    CTC_PTR_VALID_CHECK(p_cnt);

    p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
    start_idx = p_sys_league->lkup_level_start[level];
    end_idx = p_sys_league->lkup_level_start[level] + p_sys_league->lkup_level_count[level];

    step  = 1;
    for (block_idx = start_idx; block_idx < end_idx; block_idx = block_idx + step)
    {
        pe = pb->fpab.entries[block_idx];

        if(NULL==pe)
        {
            continue;
        }
        if(SYS_USW_ACL_UPA_EN(lchip, ACL_OUTER_ENTRY(pe)->group->group_info.dir))
        {
            step = 1;
        }
        else if((block_idx >= pb->fpab.start_offset[3]) && (pb->fpab.sub_entry_count[3]))        /*640 bit key*/
        {
            step = 8;
        }
        else if(block_idx >= pb->fpab.start_offset[2] && (pb->fpab.sub_entry_count[2]))   /*320 bit key*/
        {
            step = 4;
        }
        else if(block_idx >= pb->fpab.start_offset[1] && (pb->fpab.sub_entry_count[1]))   /*160 bit key*/
        {
            step = 2;
        }
        else                                            /*80 bit key*/
        {
            step = 1;
        }

        step = pb->fpab.same_size?1:step;

        if (pe)
        {
            if(CTC_ACL_KEY_IPV4 == key_type)
            {
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV4, detail, show_type, p_grep, grep_cnt, show_inner));
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV4_EXT, detail, show_type, p_grep, grep_cnt, show_inner));
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_MAC_IPV4, detail, show_type, p_grep, grep_cnt, show_inner));
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_MAC_IPV4_EXT, detail,show_type, p_grep, grep_cnt, show_inner));
            }
            else if(CTC_ACL_KEY_IPV6 == key_type)
            {
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV6, detail, show_type,p_grep, grep_cnt, show_inner));
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_IPV6_EXT, detail,show_type, p_grep, grep_cnt, show_inner));
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_MAC_IPV6, detail,show_type, p_grep, grep_cnt, show_inner));
            }
            else if(CTC_ACL_KEY_FWD == key_type)
            {
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_FWD, detail,show_type, p_grep, grep_cnt, show_inner));
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, CTC_ACL_KEY_FWD_EXT, detail,show_type, p_grep, grep_cnt, show_inner));
            }
            else
            {
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry(lchip, ACL_OUTER_ENTRY(pe), p_cnt, key_type, detail,show_type, p_grep, grep_cnt, show_inner));
            }
        }
    }

    return CTC_E_NONE;
}

/*
 * show acl entries by lookup level
 */
int32
_sys_usw_acl_show_entry_by_lkup_level(  uint8 lchip,
                                        uint8 level,
                                        uint16 key_type,
                                        uint8 detail,
                                        uint8 show_type,
                                        ctc_field_key_t* p_grep,
                                        uint8 grep_cnt,
                                        uint8 show_inner)
{
    sys_acl_block_t* pb;
    sys_acl_league_t* p_sys_league;
    uint32         count;
    uint8          block_id;
    uint8          loop;
    CTC_MAX_VALUE_CHECK(level, (p_usw_acl_master[lchip]->igs_block_num - 1));

    count = 1;
    /*loop twice, for brief entry info and detail entry info*/
    for(loop=0; loop < 2; loop++)
    {
        /*1. Ingress info*/
        p_sys_league = &(p_usw_acl_master[lchip]->league[level]);
        block_id = (p_sys_league->lkup_level_bitmap) ? level : p_sys_league->merged_to;
        pb = &SYS_ACL_BLOCK(lchip, block_id);
        if (pb->fpab.free_count != pb->fpab.entry_count) /*not empty*/
        {
            CTC_ERROR_RETURN(_sys_usw_acl_show_entry_in_lkup_level(lchip, block_id, level, pb, &count, key_type, (loop==1) ? 1:0,show_type, p_grep, grep_cnt, show_inner));
        }

        /*2. Egress info*/
        if(level < p_usw_acl_master[lchip]->egs_block_num)
        {
            p_sys_league = &(p_usw_acl_master[lchip]->league[level + p_usw_acl_master[lchip]->igs_block_num]);
            block_id = ((p_sys_league->lkup_level_bitmap) ? level + p_usw_acl_master[lchip]->igs_block_num : p_sys_league->merged_to);
            pb = &SYS_ACL_BLOCK(lchip, block_id);
            if (pb->fpab.free_count != pb->fpab.entry_count) /*not empty*/
            {
                CTC_ERROR_RETURN(_sys_usw_acl_show_entry_in_lkup_level(lchip, block_id, level, pb, &count, key_type, (loop==1) ? 1:0,show_type, p_grep, grep_cnt, show_inner));
            }
        }
        if(!detail)
        {
            break;

        }
    }
    return CTC_E_NONE;
}

/*
 * callback for hash traverse. traverse group hash table, show each group's entry.
 *
 */
STATIC int32
_sys_usw_acl_hash_traverse_cb_show_entry(sys_acl_group_t* pg, _acl_cb_para_t* cb_para)
{
    uint8 lchip = 0;

    CTC_PTR_VALID_CHECK(pg);
    CTC_PTR_VALID_CHECK(cb_para);
    lchip = pg->lchip;

    CTC_ERROR_RETURN(_sys_usw_acl_show_entry_in_group(lchip, pg,cb_para));
    return CTC_E_NONE;
}

/*
 * callback for hash traverse. traverse group hash table, show each group's group id.
 *
 */
int32
_sys_usw_acl_hash_traverse_cb_show_inner_gid(sys_acl_group_t* pg, _acl_cb_para_t* cb_para)
{
    #ifdef CTC_SHELL_DEBUG_ON
        uint8 lchip = 0;
    #endif

    CTC_PTR_VALID_CHECK(cb_para);

    #ifdef CTC_SHELL_DEBUG_ON
    lchip = cb_para->lchip;
    #endif

    if(pg->group_id>CTC_ACL_GROUP_ID_NORMAL)
    {
        cb_para->count++;
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"No.%03u  :  gid 0x%0X \n", cb_para->count, pg->group_id);
    }

    return CTC_E_NONE;
}

/*
 * callback for hash traverse. traverse group hash table, show each group's group id.
 *
 */
int32
_sys_usw_acl_hash_traverse_cb_show_outer_gid(sys_acl_group_t* pg, _acl_cb_para_t* cb_para)
{
    #ifdef CTC_SHELL_DEBUG_ON
        uint8 lchip = 0;
    #endif

    CTC_PTR_VALID_CHECK(cb_para);

    #ifdef CTC_SHELL_DEBUG_ON
    lchip = cb_para->lchip;
    #endif

    if(pg->group_id<=CTC_ACL_GROUP_ID_NORMAL)
    {
        cb_para->count++;
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"No.%03u  :  gid 0x%-X \n", cb_para->count, pg->group_id);
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_hash_traverse_cb_show_group(sys_acl_group_t* pg, _acl_cb_para_t* cb_para)
{
    char str[35];
    char format[10];
    char* dir[3] = {"IGS", "EGS", "BOTH"};
    char* type[CTC_ACL_GROUP_TYPE_MAX] = {"NONE", "HASH", "PORT_BITMAP", "GLOBAL", "VLAN_CLASS", "PORT_CLASS", "SERVICE_ACL",
                                                                       "L3IF_CLASS", "PBR_CLASS", "GPORT"};
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = cb_para->lchip;
#endif

    if(pg)
    {
        cb_para->count++;
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d", cb_para->count);

        if (SYS_ACL_SHOW_IN_HEX <= pg->group_id)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s", CTC_DEBUG_HEX_FORMAT(str, format, pg->group_id, 8, U));
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", pg->group_id);
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6s", dir[pg->group_info.dir]);
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6u", pg->group_info.block_id);

        if (pg->group_id == CTC_ACL_GROUP_ID_HASH_MAC)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-14s", "HASH_MAC");
        }
        else if (pg->group_id == CTC_ACL_GROUP_ID_HASH_IPV4)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-14s", "HASH_IPV4");
        }
        else if (pg->group_id == CTC_ACL_GROUP_ID_HASH_MPLS)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-14s", "HASH_MPLS");
        }
        else if (pg->group_id == CTC_ACL_GROUP_ID_HASH_L2_L3)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-14s", "HASH_L2L3");
        }
        else if (pg->group_id == CTC_ACL_GROUP_ID_HASH_IPV6)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-14s", "HASH_IPV6");
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-14s", type[pg->group_info.type]);
        }

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10u", pg->entry_count);

        if (pg->group_info.type == CTC_ACL_GROUP_TYPE_PORT)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"0x%-6.4x\n", pg->group_info.un.gport);
        }
        else if (pg->group_info.type == CTC_ACL_GROUP_TYPE_PORT_BITMAP)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"0x%-.8x%-.8x%-.8x%-.8x\n", pg->group_info.un.port_bitmap[0], pg->group_info.un.port_bitmap[1],
                pg->group_info.un.port_bitmap[2],pg->group_info.un.port_bitmap[3]);

        }
        else if ((pg->group_info.type == CTC_ACL_GROUP_TYPE_HASH) || (pg->group_info.type == CTC_ACL_GROUP_TYPE_GLOBAL))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-8s\n", "-");
        }
        else if (pg->group_info.type == CTC_ACL_GROUP_TYPE_PBR_CLASS)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-u\n", pg->group_info.un.pbr_class_id);
        }
        else if (pg->group_info.type == CTC_ACL_GROUP_TYPE_VLAN_CLASS)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-u\n", pg->group_info.un.vlan_class_id);
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-u\n", pg->group_info.un.port_class_id);
        }


    }

    return CTC_E_NONE;
}

/*
 * show all acl entries separate by priority or group
 * sort_type = 0: by priority
 * sort_type = 1: by group
 */
int32
_sys_usw_acl_show_entry_all(uint8 lchip,
                            uint8 sort_type,
                            uint16 key_type,
                            uint8 detail,
                            uint8 show_type,
                            ctc_field_key_t* p_grep,
                            uint8 grep_cnt,
                            uint8 show_inner)
{
    _acl_cb_para_t para;

    sal_memset(&para, 0, sizeof(_acl_cb_para_t));
    para.count = 1; /* No.*/
    para.key_type = key_type;
    para.p_grep = p_grep;
    para.grep_cnt = grep_cnt;
    para.show_type = show_type;
    para.show_inner = show_inner;

    if (sort_type == 0)
    {   /*sort tcam  --> hash */
        /* tcam entry by priority */

        para.detail   = 0;
        para.entry_type = 0;
        ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                                  (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_entry, &para);

        para.entry_type = 1;
        ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                                  (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_entry, &para);

        if(detail)
        {
            para.detail = 1;
            para.entry_type = 0;
            ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                                      (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_entry, &para);

            para.entry_type = 1;
            ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                                      (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_entry, &para);
        }
        /* hash entry by group */
    }
    else /* separate by group */
    {
        para.detail   = 0;
        para.entry_type = 2;
        ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                                  (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_entry, &para);
        if(detail)
        {
            para.detail   = 1;
            ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                                      (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_entry, &para);
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_show_spool_status(uint8 lchip)
{
    SYS_ACL_INIT_CHECK();

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6s%-18s%-12s%-10s\n","No.","name","max_count","used_cout");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d%-18s%-12u%-10u\n", 1,"ad_spool",p_usw_acl_master[lchip]->ad_spool->max_count, \
                                                        p_usw_acl_master[lchip]->ad_spool->count);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d%-18s%-12u%-10u\n", 2,"vlan_spool",p_usw_acl_master[lchip]->vlan_edit_spool->max_count, \
                                                        p_usw_acl_master[lchip]->vlan_edit_spool->count);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d%-18s%-12u%-10u\n", 3,"cid_spool",p_usw_acl_master[lchip]->cid_spool->max_count, \
                                                        p_usw_acl_master[lchip]->cid_spool->count);
    if (p_usw_acl_master[lchip]->cethertype_spool[0][CTC_INGRESS])
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d%-18s%-12u%-10u\n", 4,"cethtype_spool[0][I]",\
                                             p_usw_acl_master[lchip]->cethertype_spool[0][CTC_INGRESS]->max_count, \
                                             p_usw_acl_master[lchip]->cethertype_spool[0][CTC_INGRESS]->count);
    }
    if (p_usw_acl_master[lchip]->cethertype_spool[0][CTC_EGRESS])
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d%-18s%-12u%-10u\n", 5,"cethtype_spool[0][E]",\
                                             p_usw_acl_master[lchip]->cethertype_spool[0][CTC_EGRESS]->max_count, \
                                             p_usw_acl_master[lchip]->cethertype_spool[0][CTC_EGRESS]->count);
    }
    if(DRV_FROM_AT(lchip))
    {
        if (p_usw_acl_master[lchip]->cethertype_spool[1][CTC_INGRESS])
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d%-18s%-12u%-10u\n", 4,"cethtype_spool[1][I]",\
                                                p_usw_acl_master[lchip]->cethertype_spool[1][CTC_INGRESS]->max_count, \
                                                p_usw_acl_master[lchip]->cethertype_spool[1][CTC_INGRESS]->count);
        }
        if (p_usw_acl_master[lchip]->cethertype_spool[1][CTC_EGRESS])
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6d%-18s%-12u%-10u\n", 5,"cethtype_spool[1][E]",\
                                                p_usw_acl_master[lchip]->cethertype_spool[1][CTC_EGRESS]->max_count, \
                                                p_usw_acl_master[lchip]->cethertype_spool[1][CTC_EGRESS]->count);
        }
    }
    return CTC_E_NONE;
}

#define __ACL_OTHER__

int32
_sys_usw_acl_check_vlan_edit(uint8 lchip, ctc_acl_vlan_edit_t*   p_ctc, uint8* vlan_edit)
{
    /* check tag op */
    CTC_MAX_VALUE_CHECK(p_ctc->stag_op, CTC_ACL_VLAN_TAG_OP_MAX - 1);
    CTC_MAX_VALUE_CHECK(p_ctc->ctag_op, CTC_ACL_VLAN_TAG_OP_MAX - 1);

    if ((CTC_ACL_VLAN_TAG_OP_NONE == p_ctc->stag_op)
        && (CTC_ACL_VLAN_TAG_OP_NONE == p_ctc->ctag_op))
    {
        *vlan_edit = 0;
        return CTC_E_NONE;
    }

    *vlan_edit = 1;

    if ((CTC_ACL_VLAN_TAG_OP_ADD == p_ctc->stag_op) ||
        (CTC_ACL_VLAN_TAG_OP_REP == p_ctc->stag_op))
    {
        CTC_MAX_VALUE_CHECK(p_ctc->svid_sl, CTC_ACL_VLAN_TAG_SL_MAX - 1);
        CTC_MAX_VALUE_CHECK(p_ctc->scos_sl, CTC_ACL_VLAN_TAG_SL_MAX - 1);
        CTC_MAX_VALUE_CHECK(p_ctc->scfi_sl, CTC_ACL_VLAN_TAG_SL_MAX - 1);

        if (CTC_ACL_VLAN_TAG_SL_NEW == p_ctc->svid_sl)
        {
            CTC_MAX_VALUE_CHECK(p_ctc->svid_new, CTC_MAX_VLAN_ID);
        }
        if (CTC_ACL_VLAN_TAG_SL_NEW == p_ctc->scos_sl)
        {
            CTC_COS_RANGE_CHECK(p_ctc->scos_new);
        }
        if (CTC_ACL_VLAN_TAG_SL_NEW == p_ctc->scfi_sl)
        {
            CTC_MAX_VALUE_CHECK(p_ctc->scfi_new, 1);
        }
    }

    if ((CTC_ACL_VLAN_TAG_OP_ADD == p_ctc->ctag_op) ||
        (CTC_ACL_VLAN_TAG_OP_REP == p_ctc->ctag_op))
    {
        CTC_MAX_VALUE_CHECK(p_ctc->cvid_sl, CTC_ACL_VLAN_TAG_SL_MAX - 1);
        CTC_MAX_VALUE_CHECK(p_ctc->ccos_sl, CTC_ACL_VLAN_TAG_SL_MAX - 1);
        CTC_MAX_VALUE_CHECK(p_ctc->ccfi_sl, CTC_ACL_VLAN_TAG_SL_MAX - 1);

        if (CTC_ACL_VLAN_TAG_SL_NEW == p_ctc->cvid_sl)
        {
            CTC_MAX_VALUE_CHECK(p_ctc->cvid_new, CTC_MAX_VLAN_ID);
        }
        if (CTC_ACL_VLAN_TAG_SL_NEW == p_ctc->ccos_sl)
        {
            CTC_COS_RANGE_CHECK(p_ctc->ccos_new);
        }
        if (CTC_ACL_VLAN_TAG_SL_NEW == p_ctc->ccfi_sl)
        {
            CTC_MAX_VALUE_CHECK(p_ctc->ccfi_new, 1);
        }
    }

    if (0xFF != p_ctc->tpid_index)
    {
        CTC_MAX_VALUE_CHECK(p_ctc->tpid_index, 3);
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_add_group_key_port_field(uint8 lchip, uint32 entry_id,sys_acl_group_t* pg)
{
    ctc_field_port_t key_port;
    ctc_field_port_t key_port_mask;
    ctc_field_key_t key_field;
    uint8 is_add = 1;

    sal_memset(&key_port, 0, sizeof(ctc_field_port_t));
    sal_memset(&key_port_mask, 0, sizeof(ctc_field_port_t));
    sal_memset(&key_field, 0, sizeof(ctc_field_key_t));

    key_field.type = CTC_FIELD_KEY_PORT;
    key_field.ext_data = &key_port;
    key_field.ext_mask = &key_port_mask;

    switch (pg->group_info.type)
    {
        case CTC_ACL_GROUP_TYPE_PORT_BITMAP:
            key_port.type = CTC_FIELD_PORT_TYPE_PORT_BITMAP;
            sal_memcpy(key_port.port_bitmap, pg->group_info.un.port_bitmap, sizeof(ctc_port_bitmap_t));
            sal_memset(key_port_mask.port_bitmap, 0xFF, sizeof(ctc_port_bitmap_t));
            key_port.lchip = pg->group_info.lchip;
            break;
        case CTC_ACL_GROUP_TYPE_VLAN_CLASS :   /**< [HB.GB.GG.D2] A vlan class acl is against a class(group) of vlan*/
            key_port.vlan_class_id = pg->group_info.un.vlan_class_id;
            key_port.type = CTC_FIELD_PORT_TYPE_VLAN_CLASS;
            sal_memset(&key_port_mask.vlan_class_id, 0xFF, sizeof(key_port.vlan_class_id));
            break;
        case  CTC_ACL_GROUP_TYPE_PORT_CLASS :   /**< [HB.GB.GG.D2] A port class acl is against a class(group) of port*/
            key_port.port_class_id = pg->group_info.un.port_class_id;
            key_port.type = CTC_FIELD_PORT_TYPE_PORT_CLASS;
            sal_memset(&key_port_mask.port_class_id, 0xFF, sizeof(key_port.port_class_id));
            break;
        case CTC_ACL_GROUP_TYPE_L3IF_CLASS :   /**< [D2] A l3if class acl is against a class(group) of l3if*/
            key_port.l3if_class_id = pg->group_info.un.l3if_class_id;
            key_port.type = CTC_FIELD_PORT_TYPE_L3IF_CLASS;
            sal_memset(&key_port_mask.l3if_class_id, 0xFF, sizeof(key_port.l3if_class_id));
            break;
        case CTC_ACL_GROUP_TYPE_PBR_CLASS :    /**< [HB.GB.GG.D2] A pbr class is against a class(group) of l3 source interface*/
            key_port.pbr_class_id = pg->group_info.un.pbr_class_id;
            key_port.type = CTC_FIELD_PORT_TYPE_PBR_CLASS;
            sal_memset(&key_port_mask.pbr_class_id, 0xFF, sizeof(key_port.pbr_class_id));
            break;
        case CTC_ACL_GROUP_TYPE_PORT :        /**< [GG.D2] Port acl, care gport. */
            key_port.gport = pg->group_info.un.gport;
            key_port.type = CTC_FIELD_PORT_TYPE_GPORT;
            sal_memset(&key_port_mask.gport, 0xFF, sizeof(key_port.gport));
            break;
        case CTC_ACL_GROUP_TYPE_SERVICE_ACL :        /**< [GB.GG.D2] SERVICE_ACL, care logic port. */
            key_port.logic_port = pg->group_info.un.service_id;
            key_port.type = CTC_FIELD_PORT_TYPE_LOGIC_PORT;
            sal_memset(&key_port_mask.logic_port, 0xFF, sizeof(key_port.logic_port));
            break;
        default :
            is_add = 0;
            break;
    }
    if (is_add)
    {
        sys_acl_entry_t* pe_lkup = NULL;
        /*get entry and check*/
        _sys_usw_acl_get_entry_by_eid(lchip, entry_id, &pe_lkup);
        if (!pe_lkup )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Acl] Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        CTC_ERROR_RETURN(_sys_usw_acl_operate_key_field(lchip, pe_lkup, &key_field, 1));
    }


    return CTC_E_NONE;
}
int32 _sys_usw_acl_tcam_cid_move_cb(uint8 lchip, uint32 new_offset, uint32 old_offset, void* user_data)
{
    uint32 cmd = 0;
    DsCategoryIdPairTcamKey_m  ds_key;
    DsCategoryIdPairTcamKey_m  ds_mask;
    DsCategoryIdPairTcamAd_m     tcam_ad;
    tbl_entry_t   tcam_key;

    sal_memset(&tcam_key, 0, sizeof(tcam_key));
    sal_memset(&ds_key, 0, sizeof(ds_key));
    sal_memset(&ds_mask, 0, sizeof(ds_mask));
    sal_memset(&tcam_ad, 0, sizeof(tcam_ad));

    cmd = DRV_IOR(DsCategoryIdPairTcamAd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, old_offset, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_ad));
    cmd = DRV_IOW(DsCategoryIdPairTcamAd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, new_offset, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_ad));

    tcam_key.data_entry = (uint32*)&ds_key;
    tcam_key.mask_entry = (uint32*)&ds_mask;

    cmd = DRV_IOR(DsCategoryIdPairTcamKey_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, old_offset, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));
    cmd = DRV_IOW(DsCategoryIdPairTcamKey_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, new_offset, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));

    sal_memset(&tcam_key, 0, sizeof(tcam_key));
    cmd = DRV_IOD(DsCategoryIdPairTcamKey_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, old_offset, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));
    return CTC_E_NONE;
}

uint16
sys_usw_acl_get_ether_type_by_index(uint8 lchip, sys_acl_entry_t* pe, uint8 cether_type_index)
{
    uint16 ether_type = 0;
    uint32 cmd = 0;

    if(0 == pe->un.g4.ether_type_valid)
    {
        return ether_type;
    }

    if(SYS_ACL_GROUP_IS_PRESEL(pe->group))
    {
        uint32 ceth_type[CTC_BOTH_DIRECTION] = {ProgramAclEtherTypeCompressor_t, EgrProgramAclEtherTypeCompressor_t};
        ProgramAclEtherTypeCompressor_m cam_cethertype;
        sal_memset(&cam_cethertype,0,sizeof(ProgramAclEtherTypeCompressor_m));

        cmd = DRV_IOR(ceth_type[pe->group->group_info.dir], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, cether_type_index, DRV_CMD_PP_EN(cmd), &cam_cethertype));
        ether_type = GetProgramAclEtherTypeCompressor(V,etherType_f, &cam_cethertype);
    }
    else
    {
        EtherTypeCompressCam_m cam_cethertype;
        sal_memset(&cam_cethertype, 0 , sizeof(EtherTypeCompressCam_m));

        cmd = DRV_IOR(EtherTypeCompressCam_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, cether_type_index, DRV_CMD_PP_EN(cmd), &cam_cethertype));
        ether_type = GetEtherTypeCompressCam(V,etherType_f, &cam_cethertype);
    }

    return ether_type;
}

#define _ACL_GROUP_

#if 0
int32
_sys_usw_acl_judge_ad_type_by_aset(uint8 lchip, uint8 action_type, uint32* aset, uint8* ad_type_o)
{
    uint8  ad_type = SYS_ACL_AD_TYPE_NONE;
    uint32 ad_id = 0;

    CTC_BMP__ITER(aset, CTC_ACL_FIELD_ACTION_NUM, ad_id)
    {
        switch(ad_id)
        {
        case CTC_ACL_FIELD_ACTION_CANCEL_ALL:
            break;
        case CTC_ACL_FIELD_ACTION_COLOR:
        case CTC_ACL_FIELD_ACTION_PRIORITY:
        case CTC_ACL_FIELD_ACTION_QOS_TABLE_MAP:
            /*if(CTC_INGRESS == dir)
            {
                SYS_ACL_JUDGE_AD_TYPE(ad_type, !ad_type, SYS_ACL_AD_TYPE_PERMIT)
            }*/
            break;
        case CTC_ACL_FIELD_ACTION_REDIRECT_PORT:
        case CTC_ACL_FIELD_ACTION_REDIRECT:
            if(SYS_ACL_ACTION_TCAM_INGRESS == action_type)
            {
                SYS_ACL_JUDGE_AD_TYPE(ad_type, !ad_type, SYS_ACL_AD_TYPE_REDIRECT);
            }
            break;
        case CTC_ACL_FIELD_ACTION_MICRO_FLOW_POLICER:
        case CTC_ACL_FIELD_ACTION_MACRO_FLOW_POLICER:
        case CTC_ACL_FIELD_ACTION_COS_HBWP_POLICER:
            break;
        case CTC_ACL_FIELD_ACTION_STATS:
            SYS_ACL_JUDGE_AD_TYPE(ad_type, !ad_type, SYS_ACL_AD_TYPE_STATS);
            break;
        case CTC_ACL_FIELD_ACTION_CP_TO_CPU:
            SYS_ACL_JUDGE_AD_TYPE(ad_type, !ad_type, SYS_ACL_AD_TYPE_EXCEPTION);
            break;
        default:
            ad_type = SYS_ACL_AD_TYPE_DISABLE;
            break;
        }

        if(SYS_ACL_AD_TYPE_DISABLE == ad_type)
        {
            break;
        }
    }

    *ad_type_o = ad_type;

    return CTC_E_NONE;
}
#endif

uint32
_sys_acl_get_xdata_v_bit(uint32* bmp, uint32 width, uint32 offset)
{
    int32 cnt = 0;
    CTC_BMP_COUNT_RANGE(bmp, cnt, offset, width);
    return cnt;
}

int32
sys_usw_acl_offset_map_chunk(ctc_xdata_field_t* field, uint8 dir, uint32* chunk_bmp_o, uint8 is_flowhash)
{
    uint8 start = field->offset;
    uint16 chunk_bmp = 0;
    uint32 xdata_data[3] = {0};

    if(is_flowhash)
    {
        CTC_BMP_SET_RANGE(xdata_data, field->offset, field->width);
        if(_sys_acl_get_xdata_v_bit(xdata_data, 16, 0) ||
           _sys_acl_get_xdata_v_bit(xdata_data, 8, 32) ||
           _sys_acl_get_xdata_v_bit(xdata_data, 12, 48))
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_FLOW_CHUNK0);
        }

        if(_sys_acl_get_xdata_v_bit(xdata_data, 16, 16))/* categoryIdOrServiceId */
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_FLOW_CHUNK1);
        }

        if(_sys_acl_get_xdata_v_bit(xdata_data, 8, 40) ||
           _sys_acl_get_xdata_v_bit(xdata_data, 4, 60))/* metadata */
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_FLOW_CHUNK2);
        }

        if(_sys_acl_get_xdata_v_bit(xdata_data, 4, 64))/* auxData*/
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_FLOW_CHUNK3);
        }

        if(CTC_FLAG_ISSET(field->flag, CTC_XDATA_FIELD_FLAG_UDF))/* udf exist*/
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_FLOW_CHUNK4);
        }
        *chunk_bmp_o |= chunk_bmp;

        return CTC_E_NONE;
    }



    if(CTC_INGRESS == dir)
    {
        if(CTC_FLAG_ISSET(field->flag, CTC_XDATA_FIELD_FLAG_UDF))
        {
            /*if use udf, only word[0] need check union*/
            if(start<16)
            {
                CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK3_WORD0_UDF);
            }
        }
        else
        {
            if(start<16)
            {
                CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK3_WORD0);        /*0-16*/
            }else if(start<32)
            {
                CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK4_WORD1);        /*16-32*/
            }else if(start<48)
            {
                CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK2_BYTE1_0);      /*32-48*/
            }else if(start<64)
            {
                CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK1_NIBBLE3_0);    /*48-64*/
            }else
            {
                CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK0_NIBBLE4);      /*64-68*/
            }
        }
    }
    else
    {
        if(start<16)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_EGS_CHUNK2_BYTE1_WORD0);
        }else if(start<32)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_EGS_CHUNK3_WORD1);
        }else if(start<40)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_EGS_CHUNK1_NIBBLE3_0_BYTE0);
            if(field->width > 8)
            {
                /*offset 32, width 16 ; have 2 chunk*/
                CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_EGS_CHUNK2_BYTE1_WORD0);
            }
        }else if(start<48)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_EGS_CHUNK2_BYTE1_WORD0);
        }else if(start<64)
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_EGS_CHUNK1_NIBBLE3_0_BYTE0);
        }else
        {
            CTC_SET_FLAG(chunk_bmp, SYS_ACL_XDATA_EGS_CHUNK0_NIBBLE4);
        }
    }
    *chunk_bmp_o |= chunk_bmp;

    return 0;
}

int32 _sys_usw_acl_check_xdata(uint8 lchip, uint8 action_type, sys_acl_group_t* pg, uint8 prof_id, uint32* aset, ctc_xdata_t* in_xdata)
{
    uint8 loop = 0;
    uint32 chunk_bmp = 0;
    uint8 dir = (action_type == SYS_ACL_ACTION_TCAM_EGRESS) ? CTC_EGRESS : CTC_INGRESS;
    uint8 priority = pg ? pg->group_info.block_id : 0;
    uint8 is_flowhash = (action_type == SYS_ACL_ACTION_HASH_INGRESS) ? 1 : 0;
    ctc_xdata_t xdata;
    ctc_xdata_t* p_xdata = in_xdata;
    ctc_xdata_field_t fields[9];


    if(!in_xdata)
    {
        sal_memset(&xdata, 0, sizeof(ctc_xdata_t));
        sal_memset(&fields, 0, sizeof(fields));
        xdata.prof_id = prof_id;
        xdata.fields = fields;
        xdata.type = is_flowhash ? CTC_XDATA_PROF_TYPE_DSFLOW:((CTC_INGRESS==dir) ? CTC_XDATA_PROF_TYPE_DSACL:CTC_XDATA_PROF_TYPE_EGS_DSACL);
        CTC_ERROR_RETURN(DRV_FROM_AT(lchip)? CTC_E_NONE: CTC_E_NOT_SUPPORT);
        CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->prof_get_info(lchip, &xdata, FALSE));
        p_xdata = &xdata;
    }

    /*get chunk bmp*/
    do
    {
        sys_usw_acl_offset_map_chunk(p_xdata->fields+loop, dir, &chunk_bmp, is_flowhash);
    }while(++loop<p_xdata->num);

    if(is_flowhash)
    {
        CTC_MAX_VALUE_CHECK(priority, 2);
        /* flow hash priority 1 only support profile 0 */
        if(priority==1 && prof_id != 0)
        {
            return CTC_E_INVALID_PARAM;
        }
        if(CTC_FLAG_ISSET(chunk_bmp,SYS_ACL_XDATA_FLOW_CHUNK0) 
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REDIRECT)
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REDIRECT_PORT)))
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if(CTC_FLAG_ISSET(chunk_bmp,SYS_ACL_XDATA_FLOW_CHUNK1)
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NSH)
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DEST_CID)
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SRC_CID)
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SERVICE_ID)
        || priority==1
        || priority==2))
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if(CTC_FLAG_ISSET(chunk_bmp,SYS_ACL_XDATA_FLOW_CHUNK2)
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_METADATA)
        || priority==1
        || priority==2))
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if(priority==1 && CTC_FLAG_ISSET(chunk_bmp,SYS_ACL_XDATA_FLOW_CHUNK3))
        {
            return CTC_E_PARAM_CONFLICT;
        }

        /* flow hash not support udf */
        if(CTC_FLAG_ISSET(chunk_bmp,SYS_ACL_XDATA_FLOW_CHUNK4))
        {
            return CTC_E_NOT_SUPPORT;
        }

        return CTC_E_NONE;
    }

    if (CTC_INGRESS == dir)
    {
        if(CTC_FLAG_ISSET(chunk_bmp,SYS_ACL_XDATA_IGS_CHUNK1_NIBBLE3_0)
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_STRIP_PACKET)))
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if(CTC_FLAG_ISSET(chunk_bmp,SYS_ACL_XDATA_IGS_CHUNK2_BYTE1_0)
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NSH) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH) ||  CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_METADATA) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_FID) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SPAN_FLOW) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DISABLE_ECMP_RR) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DISABLE_LINKAGG_RR) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_LB_HASH_ECMP_PROFILE) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_LB_HASH_LAG_PROFILE) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_LB_HASH_PROFILE) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_CUT_THROUGH)|| CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT)
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DISABLE_ECMP_DLB)))
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if(CTC_FLAG_ISSET(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK3_WORD0) 
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REDIRECT) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SERVICE_ID) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SRC_CID) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_STATS)))
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if(CTC_FLAG_ISSET(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK3_WORD0_UDF) 
        && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SERVICE_ID))
        {
            /*word[0] use udf need check*/
            return CTC_E_PARAM_CONFLICT;
        }
        /*word[1] only use udf , no need check
        if(CTC_FLAG_ISSET(chunk_bmp, SYS_ACL_XDATA_IGS_CHUNK4_WORD1))
        {
            
        }*/
    }
    else
    {
        if(CTC_FLAG_ISSET(chunk_bmp ,SYS_ACL_XDATA_EGS_CHUNK1_NIBBLE3_0_BYTE0)
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT)))
        {
            return CTC_E_PARAM_CONFLICT;
        }
        if(CTC_FLAG_ISSET(chunk_bmp ,SYS_ACL_XDATA_EGS_CHUNK2_BYTE1_WORD0) 
        && (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) 
        || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_OAM)))
        {
            return CTC_E_PARAM_CONFLICT;
        }
        if(CTC_FLAG_ISSET(chunk_bmp ,SYS_ACL_XDATA_EGS_CHUNK3_WORD1))
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }
    return CTC_E_NONE;
}


int32
_sys_usw_acl_check_aset(uint8 lchip, uint8 action_type, sys_acl_aset_t* p_aset)
{
    uint8 g1_flag = 0, g2_flag = 0, g3_flag = 0, g4_flag = 0, g1_or_g2 = 0;
    uint8 sts_is_u3 = 0;
    uint8 mode = 1;
    #if 1
    uint16 aset_word = CTC_B2W_SIZE(CTC_ACL_FIELD_ACTION_NUM);
    uint32* aset = p_aset->w;
    ctc_acl_aset_t* aset_base = &p_usw_acl_master[lchip]->support_aset[action_type];
    uint8 i = 0;

    p_aset->type = action_type;

    for(i = 0; i < aset_word; i++)
    {   /* cfg action field is out of the support aset */
        if(~aset_base->w[i] & aset[i])
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Aset out of support, error aset:0x%x, word:%d.\n", (~aset_base->w[i] & aset[i]), i);
            return CTC_E_NOT_SUPPORT;
        }
    }
    #endif

    /* both dir */
    if(mode)
    {
        g1_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_MACRO_FLOW_POLICER) ? 1 : 0;
        g2_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_MICRO_FLOW_POLICER) ? 1 : 0;
        g3_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_COPP) ? 1 : 0;
        g4_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_COS_HBWP_POLICER) ? 1 : 0;
        if(g1_flag + g2_flag + g3_flag + g4_flag > 1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "policer conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }
        /* ipfixOpCode */
       if( !CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX) +
            !(CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_CANCEL_IPFIX)) +
            !CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_CANCEL_IPFIX_LEARNING) +
            !CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID) < 3)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "ipfixOpCode conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }
    }

    if(SYS_ACL_ACTION_HASH_INGRESS == action_type)
    {
        uint8 is_half_ad = 0;
        CTC_ERROR_RETURN(sys_usw_global_get_flow_record_en(lchip, &is_half_ad));
        if(is_half_ad)
        {
            if(!(CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DISCARD) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REDIRECT_PORT) || \
                 CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REDIRECT) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_MICRO_FLOW_POLICER) || \
                 CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_MACRO_FLOW_POLICER) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_COS_HBWP_POLICER) || \
                 CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_CANCEL_ALL) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_COPP) ||
                 CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_STATS) ||CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_CANCEL_ACL_TCAM_EN)) )
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Do not support action for ds flow half ad\n");
                return CTC_E_NOT_SUPPORT;
            }
        }
        if(mode)
        {
            g1_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NSH) ? 1 : 0;
            g2_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DEST_CID) ? 1 : 0;
            g3_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SRC_CID) ? 1 : 0;
            g4_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SERVICE_ID) ? 1 : 0;
            if(g1_flag + g2_flag + g3_flag + g4_flag > 1)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "categoryId conflict \n");
                return CTC_E_PARAM_CONFLICT;
            }
        }
    }
    else if ( SYS_ACL_ACTION_TCAM_EGRESS == action_type && DRV_FROM_TMM(lchip))
    {
        /* u1 check */
        g1_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) ? SYS_AD_UNION_G_1 : 0;
        g3_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT) ? SYS_AD_UNION_G_3 : 0;
        if(!g1_flag + !g3_flag < 1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "u1 conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }
        p_aset->u1_type = g1_flag + g3_flag;

        /* u2 check */
        g1_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) ? SYS_AD_UNION_G_1 : 0;
        g2_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_OAM) ? SYS_AD_UNION_G_2 : 0;
        g3_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX) ? SYS_AD_UNION_G_3 : 0;
        if(!g1_flag + !g2_flag + !g3_flag < 2)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "u2 conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }
        p_aset->u2_type = g1_flag + g2_flag + g3_flag;
    }
    else    /* igs tcam */
    {
        /* u2 check */
        g1_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SRC_CID) ? SYS_AD_UNION_G_1 : 0;
        g2_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX) ? SYS_AD_UNION_G_2 : 0;
        g3_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SERVICE_ID) ? SYS_AD_UNION_G_3 : 0;
        if((g1_flag + g2_flag + g3_flag) && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            sts_is_u3 = CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_STATS);
        }
        else
        {
            g4_flag = CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_STATS) ? SYS_AD_UNION_G_4 : 0;
        }
        if(!g1_flag + !g2_flag + !g3_flag + !g4_flag >= 3)
        {
            p_aset->u2_type = g3_flag + g2_flag + g1_flag + g4_flag;
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "u2 conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }

        /* intSession */
        if((!(mode && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID)) + !sts_is_u3 +
            !CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_INT) +
            !CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IFA) +
            !CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REDIRECT_CANCEL_PKT_EDIT) ) < 4)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "intSession conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }

        /* u4 check */
        g2_flag = (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) && mode) ? SYS_AD_UNION_G_2 : 0;
        g1_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_STRIP_PACKET) ? SYS_AD_UNION_G_1 : 0;
        if((g2_flag || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REDIRECT_CANCEL_PKT_EDIT)) && g1_flag )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "u4 conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }
        p_aset->u4_type = g2_flag + g1_flag;


        /* u3 check */
        /* use same union check */
        if((CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT)) || /*u3_gReplaceLbHashOperation*/
           (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_METADATA ) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_FID)) ) /* u3_gMetadata */
        {
            return CTC_E_PARAM_CONFLICT;
        }
           /* u3_gcvlan */
        if( !(CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) && mode)+
            !CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NSH) +
            !sts_is_u3 < 2 )
        {
            return CTC_E_PARAM_CONFLICT;
        }

        g4_flag = DRV_IS_DUET2(lchip) ? 0 : ( CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH) ||
                                              CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT) ||
                                              (DRV_FROM_TMM(lchip) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DISABLE_ECMP_DLB)) ||
                                              (DRV_IS_TSINGMA(lchip) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_CUT_THROUGH )) ? SYS_AD_UNION_G_4 : 0);
        g3_flag = (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_LB_HASH_ECMP_PROFILE ) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_LB_HASH_LAG_PROFILE)) ? SYS_AD_UNION_G_3 : 0;
        if(CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DISABLE_ECMP_RR) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DISABLE_LINKAGG_RR))
        {
            g3_flag = ( (g3_flag + g4_flag) && DRV_FROM_TMM(lchip) ) ? g3_flag : SYS_AD_UNION_G_3;
        }
        g2_flag = (CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_METADATA ) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_SPAN_FLOW) || CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_FID)) ? SYS_AD_UNION_G_2 : 0;
        g1_flag = ( CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VLAN_EDIT) || sts_is_u3 ||
                    (DRV_FROM_AT(lchip) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NSH)) ) ? SYS_AD_UNION_G_1 : 0;
        if(!g1_flag + !g2_flag + !g3_flag + !g4_flag >= 3)
        {
            p_aset->u3_type = g4_flag + g3_flag + g2_flag + g1_flag;
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "u3 conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }

        if(CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID) && 
            (p_aset->u2_type || p_aset->u3_type || p_aset->u4_type) && mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "npm im flow conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }

        /* u1 check */
        g2_flag = 0;
        g1_flag = ( CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_INTER_CN) ||
                    CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_TRUNCATED_LEN) ||
                    (DRV_IS_DUET2(lchip) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH))|| 
                    (DRV_FROM_TMM(lchip) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_CP_TO_CPU) && !(CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_REDIRECT_PORT) || CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_REDIRECT) || CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_OAM)))) ? SYS_AD_UNION_G_1 : 0;
        g3_flag = CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_OAM) ? SYS_AD_UNION_G_3 : 0;
        g1_or_g2 = (CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_REDIRECT_PORT) || CTC_BMP_ISSET(aset,CTC_ACL_FIELD_ACTION_REDIRECT)) ? 1 : 0;
        if(DRV_IS_TSINGMA(lchip) && SYS_ACL_ACTION_TCAM_EGRESS == action_type)
        {
            g2_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_VXLAN_RSV_EDIT) ? SYS_AD_UNION_G_2 : 0;
            if(g2_flag && g1_or_g2)
            {
                return CTC_E_PARAM_CONFLICT;
            }
        }
        if((!g1_flag + !g2_flag + !g3_flag < 2) || (g1_or_g2 && g3_flag))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "u1 conflict \n");
            return CTC_E_PARAM_CONFLICT;
        }
        else
        {
            p_aset->u1_type = g3_flag + g1_flag + g2_flag;
        }

        /* u5 check */
        if(!DRV_FROM_TMM(lchip))
        {
            g1_flag = CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_RANDOM_LOG) ? SYS_AD_UNION_G_1 : 0;
            g3_flag = ( CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_IPFIX) && mode ) ? SYS_AD_UNION_G_3 : 0;
            if(g1_flag && g3_flag)
            {
                return CTC_E_PARAM_CONFLICT;
            }
            else
            {
                p_aset->u5_type = g1_flag + g3_flag;
            }
        }
    }
    if(DRV_FROM_AT(lchip) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_XDATA) && SYS_ACL_ACTION_TCAM_INGRESS != action_type)
    {
        CTC_ERROR_RETURN(_sys_usw_acl_check_xdata(lchip, action_type, NULL, p_aset->xdata_prof_id, aset,NULL));
    }
    if (!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && CTC_BMP_ISSET(aset, CTC_ACL_FIELD_ACTION_DOT1AE_CHAN_ID))
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_add_aset(uint8 lchip, uint8 action_type, ctc_acl_aset_t* ctc_aset, sys_acl_aset_t** p_sys_aset)
{
    int32 ret = 0;
    uint32 offset = 0;
    sys_acl_aset_t* aset;
    sys_usw_opf_t opf;

    aset = mem_malloc(MEM_ACL_MODULE, sizeof(sys_acl_aset_t));
    if(aset == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(aset, 0, sizeof(sys_acl_aset_t));
    sal_memcpy(aset->w, ctc_aset->w, sizeof(aset->w));
    sal_memset(&opf, 0, sizeof(opf));

    CTC_BMP_SET(aset->w, CTC_ACL_FIELD_ACTION_CANCEL_ALL);

    opf.pool_type = p_usw_acl_master[lchip]->opf_type_aset;
    if(ctc_aset->aset_id)
    {
        CTC_ERROR_GOTO(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, ctc_aset->aset_id), ret, error0);
    }
    else
    {
        CTC_ERROR_GOTO(sys_usw_opf_alloc_offset(lchip, &opf, 1, &offset), ret, error0);
        ctc_aset->aset_id = offset;
    }

    aset->aset_id = ctc_aset->aset_id;
    aset->xdata_prof_id = ctc_aset->xdata_prof_id;
    CTC_ERROR_GOTO(_sys_usw_acl_check_aset(lchip, action_type, aset), ret, error1);
    CTC_ERROR_GOTO(ctc_vector_add(p_usw_acl_master[lchip]->aset_vec, aset->aset_id, aset), ret, error1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_ASET, 1);

    *p_sys_aset = aset;
    return CTC_E_NONE;
    
error1:
    sys_usw_opf_free_offset(lchip, &opf, 1, ctc_aset->aset_id);
error0:
    mem_free(aset);
    return ret;
}

int32
_sys_usw_acl_get_aset(uint8 lchip, uint16 aset_id, sys_acl_aset_t** p_aset)
{
    sys_acl_aset_t* p_a = NULL;

    p_a = ctc_vector_get(p_usw_acl_master[lchip]->aset_vec, aset_id);
    if(p_a == NULL)
    {
        return CTC_E_NOT_EXIST;
    }
    *p_aset = p_a;
    
    return CTC_E_NONE;
}


int32
_sys_usw_acl_remove_aset(uint8 lchip, uint16 aset_id)
{
    sys_usw_opf_t opf;
    sys_acl_aset_t* p_aset = NULL;
    uint8 pp_base = drv_vchip_get_pp_base(lchip);

    p_aset = ctc_vector_get(p_usw_acl_master[pp_base]->aset_vec, aset_id); 
    if(!p_aset)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"Aset Not Found\n");
        return CTC_E_NONE;
    }
    if(SYS_ACL_ASET_IS_DEF(aset_id))
    {
        if(p_aset->ref_cnt)
        {
           p_aset->ref_cnt--;
        }
        return CTC_E_NONE;
    }
    /* no static aset create by add entry/group, destroy by remove entry/group */
    if(p_aset && p_aset->ref_cnt)
    {
        p_aset->ref_cnt--;
        if(p_aset->is_static || p_aset->ref_cnt)
        {
            return CTC_E_NONE;
        }
    }

    sal_memset(&opf, 0, sizeof(opf));
    opf.pool_type = p_usw_acl_master[pp_base]->opf_type_aset;
    sys_usw_opf_free_offset(pp_base, &opf, 1, aset_id);
    
    ctc_vector_del(p_usw_acl_master[pp_base]->aset_vec, aset_id);
    mem_free(p_aset);
    SYS_USW_REGISTER_WB_SYNC_EN(pp_base, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_ASET, 1);
    
    return CTC_E_NONE;
}


void
_sys_usw_acl_update_aset_ref(uint8 lchip, uint8 aset_id)
{
    sys_acl_aset_t* p_aset = NULL;
    p_aset = ctc_vector_get(p_usw_acl_master[lchip]->aset_vec, aset_id);
    if(p_aset)
    {
        p_aset->ref_cnt++;
    }
}

int32
_sys_usw_acl_create_group(uint8 lchip, uint32 group_id, ctc_acl_group_info_t* group_info)
{
    sys_acl_group_t* pg_new = NULL;
    int32          ret;
    sys_acl_block_t* pb;
    uint32 block_id = 0;
    sys_acl_aset_t* p_aset = NULL;
    uint8 action_type = SYS_ACL_ACTION_TCAM_INGRESS;

    #ifdef WARMBOOT
    if(CTC_WB_ENABLE(lchip) && p_usw_acl_master[lchip]->group->count >= SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_ACL_GROUP))
    {
        return CTC_E_NO_RESOURCE;
    }
    #endif
    /* malloc an empty group */
    MALLOC_ZERO(MEM_ACL_MODULE, pg_new, sizeof(sys_acl_group_t));
    if (!pg_new)
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }
    pg_new->lchip = lchip;
    if (!SYS_ACL_IS_RSV_GROUP(group_id))
    {
        if (!group_info)
        {
            ret = CTC_E_INVALID_PARAM;
            goto error1;
        }

        CTC_ERROR_GOTO(_sys_usw_acl_check_group_info(lchip, group_info, group_info->type, 1, ACL_BITMAP_STATUS_64), ret, error1);
        CTC_ERROR_GOTO(_sys_usw_acl_map_group_info(lchip, &pg_new->group_info, group_info, 1), ret, error1);
        if ( ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && (group_info->dir == CTC_INGRESS)) || DRV_FROM_AT(lchip) )
        {
            CTC_SET_FLAG(pg_new->flag, SYS_ACL_GROUP_FLAG_PRESEL);
        }

        block_id = (CTC_INGRESS == pg_new->group_info.dir ? pg_new->group_info.block_id: pg_new->group_info.block_id + ACL_IGS_BLOCK_MAX_NUM);
        pb = &SYS_ACL_BLOCK(lchip, block_id);
        ctc_slist_add_tail(pb->group_list, &pg_new->head);
    }
    else
    {
        pg_new->group_info.type = CTC_ACL_GROUP_TYPE_HASH;
    }

    pg_new->group_id = group_id;
    action_type = (group_info->type == CTC_ACL_GROUP_TYPE_HASH) ? SYS_ACL_ACTION_HASH_INGRESS :
            (CTC_INGRESS == pg_new->group_info.dir ? SYS_ACL_ACTION_TCAM_INGRESS : SYS_ACL_ACTION_TCAM_EGRESS);

    ctc_list_pointer_init(&(pg_new->entry_list));

    CTC_ERROR_GOTO(_sys_usw_acl_operate_aset(lchip, group_info->aset, action_type, &p_aset), ret, error2);
    pg_new->aset_id = p_aset->aset_id;
    
    /* add to hash */
    if (NULL == ctc_hash_insert(p_usw_acl_master[lchip]->group, pg_new))
    {
        ret = CTC_E_NO_MEMORY;
        goto error3;
    }
#if 0
    if (SYS_ACL_SUPPORT_PRESEL(lchip) &&
        SYS_ACL_GROUP_IS_PRESEL(pg_new))
    {
        ret = MCHIP_ACL(lchip)->create_group(lchip, group_id, group_info);
        if (ret)
        {
            goto error3;
        }
    }
#endif
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_GROUP, 1);
    return CTC_E_NONE;

//error3:
    //ctc_hash_remove(p_usw_acl_master[lchip]->group, pg_new);

error3:
    _sys_usw_acl_remove_aset(lchip, p_aset->aset_id);
error2:
    if (!SYS_ACL_IS_RSV_GROUP(group_id))
    {
        pb = &SYS_ACL_BLOCK(lchip, block_id);
        ctc_slist_delete_node(pb->group_list, &pg_new->head);
    }
error1:
    mem_free(pg_new);
error0:
    return ret;
}

int32
_sys_usw_acl_destroy_group(uint8 lchip, uint32 group_id)
{
    sys_acl_group_t* pg = NULL;
    sys_acl_block_t* pb;
    uint8 block_id = 0;
    /* check if group exist */
    CTC_ERROR_RETURN(_sys_usw_acl_get_group_by_gid(lchip, group_id, &pg));
    if (!pg)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Acl] Group not exist \n");
        return CTC_E_NOT_EXIST;
    }


    /* check if all entry removed */
    if (0 != pg->entry_list.count)
    {
        return CTC_E_NOT_READY;
    }
#if 0
    if (SYS_ACL_SUPPORT_PRESEL(lchip) &&
        SYS_ACL_GROUP_IS_PRESEL(pg))
    {
        CTC_ERROR_RETURN(MCHIP_ACL(lchip)->destroy_group(lchip, group_id));
    }
#endif
    block_id = (CTC_INGRESS == pg->group_info.dir ? pg->group_info.block_id: pg->group_info.block_id + ACL_IGS_BLOCK_MAX_NUM);
    pb = &SYS_ACL_BLOCK(lchip, block_id);
    if (!SYS_ACL_IS_RSV_GROUP(group_id))
    {
        ctc_slist_delete_node(pb->group_list, &pg->head);
    }

    ctc_hash_remove(p_usw_acl_master[lchip]->group, pg);

    /*free group aset */
    _sys_usw_acl_remove_aset(lchip, pg->aset_id);

    /* free pg */
    mem_free(pg);

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_GROUP, 1);

    return CTC_E_NONE;
}

int32
_sys_usw_acl_install_group(uint8 lchip, uint32 group_id, ctc_acl_group_info_t* group_info)
{
    sys_acl_group_t       * pg = NULL;
    ctc_list_pointer_node_t* pe_node = NULL;
    int32                 ret = CTC_E_NONE;
    int32                 ret_temp = CTC_E_NONE;
    uint32                eid = 0;

    /* get group node */
    CTC_ERROR_RETURN(_sys_usw_acl_get_group_by_gid(lchip, group_id, &pg));
    if (!pg)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Acl] Group not exist \n");
        return CTC_E_NOT_EXIST;
    }

    /* traverse, stop at first installed entry.*/
    for (pe_node = ctc_list_pointer_head(&(pg->entry_list));
         pe_node && !ACL_ENTRY_IS_INSTALLED((sys_acl_entry_t*)pe_node);
         pe_node = ctc_list_pointer_next(pe_node))
    {
        ret_temp = _sys_usw_acl_install_entry(lchip, (sys_acl_entry_t *) pe_node, SYS_ACL_ENTRY_OP_FLAG_ADD, 0);
        if(CTC_E_NONE != ret_temp)
        {
            ret = ret_temp;
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"sys_usw_acl_install_group(),install entry (eid: %u)failed!\n",eid);
        }
    }

    return ret;
}

int32
_sys_usw_acl_uninstall_group(uint8 lchip, uint32 group_id)
{
    sys_acl_group_t       * pg = NULL;
    ctc_list_pointer_node_t* pe = NULL;

    /* get group node */
    CTC_ERROR_RETURN(_sys_usw_acl_get_group_by_gid(lchip, group_id, &pg));
    if (!pg)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Acl] Group not exist \n");
        return CTC_E_NOT_EXIST;
    }

    CTC_LIST_POINTER_LOOP(pe, &(pg->entry_list))
    {
        CTC_ERROR_RETURN(_sys_usw_acl_install_entry(lchip, (sys_acl_entry_t *) pe, SYS_ACL_ENTRY_OP_FLAG_DELETE, 0));
    }

    return CTC_E_NONE;
}

#define _ACL_ENTRY_

int32 
_sys_usw_acl_check_entry_cnt(uint8 lchip, sys_acl_entry_t* pe)
{
    int32 ret = CTC_E_NONE;
#ifdef WARMBOOT
    uint8  key_size = 0;
    uint8  temp_step = 0;
    uint8  ftm_spc = 0;
    uint32 entry_cnt = 0;

    if(ACL_ENTRY_IS_TCAM(pe))
    {
        key_size = _sys_usw_acl_get_key_size(lchip, 0, pe, &temp_step);
        if(SYS_ACL_GROUP_IS_PRESEL(pe->group))
        {
            entry_cnt = p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_160]  + key_size;
        }
        else
        {
            
            entry_cnt =  (p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_80])
                        + (p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_160]*2)
                        + (p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_320]*4)
                        + (p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_TCAM_640]*8)
                        + temp_step;
        }
        ftm_spc = CTC_FTM_SPEC_ACL;
    }
    else
    {
        _sys_usw_acl_get_key_size(lchip, 1, (void*)pe, &temp_step);
        entry_cnt = p_usw_acl_master[lchip]->key_count[ACL_ALLOC_COUNT_HASH] + temp_step; 
        ftm_spc = CTC_FTM_SPEC_ACL_FLOW;
    }
    if( CTC_WB_ENABLE(lchip) &&  (entry_cnt > SYS_FTM_SPEC(lchip, ftm_spc)) )
    {
        return CTC_E_NO_RESOURCE;
    }
#endif

    return ret;
}


/*
 * check entry type if it is valid.
 */
int32
sys_usw_acl_check_entry_type(uint8 lchip, uint32 group_id, sys_acl_group_t* pg, ctc_acl_entry_t* p_ctc_entry)
{
    //CTC_PTR_VALID_CHECK(p_ctc_entry);in sys_usw_acl_add_entry
    //CTC_PTR_VALID_CHECK(pg); in _sys_usw_acl_add_entry
    if ((CTC_EGRESS == pg->group_info.dir) &&
        (CTC_ACL_KEY_CID == p_ctc_entry->key_type ||
         CTC_ACL_KEY_UDF == p_ctc_entry->key_type ||
         CTC_ACL_KEY_FWD == p_ctc_entry->key_type ||
         CTC_ACL_KEY_FWD_EXT == p_ctc_entry->key_type ||
         CTC_ACL_KEY_COPP == p_ctc_entry->key_type ||
         CTC_ACL_KEY_COPP_EXT == p_ctc_entry->key_type ||
         CTC_ACL_KEY_STK_HDR == p_ctc_entry->key_type))
    {
        return CTC_E_INVALID_PARAM;
    }
    if (DRV_FROM_TMM(lchip) &&
        (CTC_EGRESS == pg->group_info.dir) &&
        (CTC_ACL_KEY_INTERFACE == p_ctc_entry->key_type ||
         CTC_ACL_KEY_UDF == p_ctc_entry->key_type))
    {
        return CTC_E_INVALID_PARAM;
    }
    switch (p_ctc_entry->key_type)
    {
    case CTC_ACL_KEY_STK_HDR:
        if(!DRV_FROM_TMM(lchip))
        {
            return CTC_E_NOT_SUPPORT;
        }
    case CTC_ACL_KEY_MAC:
    case CTC_ACL_KEY_IPV4:
    case CTC_ACL_KEY_IPV4_EXT:
    case CTC_ACL_KEY_MAC_IPV4:
    case CTC_ACL_KEY_MAC_IPV4_EXT:
    case CTC_ACL_KEY_IPV6:
    case CTC_ACL_KEY_IPV6_EXT:
    case CTC_ACL_KEY_MAC_IPV6:
    case CTC_ACL_KEY_CID:
    case CTC_ACL_KEY_INTERFACE:
    case CTC_ACL_KEY_FWD:
    case CTC_ACL_KEY_FWD_EXT:
    case CTC_ACL_KEY_UDF :
        if (CTC_ACL_GROUP_TYPE_HASH == pg->group_info.type)
        {
            return CTC_E_INVALID_PARAM;
        }
    break;

    case CTC_ACL_KEY_COPP:
    case CTC_ACL_KEY_COPP_EXT:
        if ((CTC_ACL_GROUP_TYPE_GLOBAL != pg->group_info.type) && (CTC_ACL_GROUP_TYPE_PORT_BITMAP != pg->group_info.type) && (CTC_ACL_GROUP_TYPE_NONE != pg->group_info.type))
        {
            return CTC_E_INVALID_PARAM;
        }
        break;

    case CTC_ACL_KEY_HASH_MAC:
    case CTC_ACL_KEY_HASH_IPV4:
    case CTC_ACL_KEY_HASH_IPV6:
    case CTC_ACL_KEY_HASH_MPLS:
    case CTC_ACL_KEY_HASH_L2_L3:
        if(((CTC_ACL_GROUP_ID_HASH_MAC == group_id)&&(CTC_ACL_KEY_HASH_MAC!=p_ctc_entry->key_type))
            ||((CTC_ACL_GROUP_ID_HASH_IPV4 == group_id)&&(CTC_ACL_KEY_HASH_IPV4!=p_ctc_entry->key_type))
            ||((CTC_ACL_GROUP_ID_HASH_MPLS == group_id)&&(CTC_ACL_KEY_HASH_MPLS!=p_ctc_entry->key_type))
            ||((CTC_ACL_GROUP_ID_HASH_L2_L3 == group_id)&&(CTC_ACL_KEY_HASH_L2_L3!=p_ctc_entry->key_type))
            ||((CTC_ACL_GROUP_ID_HASH_IPV6 == group_id)&&(CTC_ACL_KEY_HASH_IPV6!=p_ctc_entry->key_type)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The Key Type is not include in The Group.\n  The Group Id is :0x%x ,The Key Type is :%d\n", group_id, p_ctc_entry->key_type);
            return CTC_E_INVALID_PARAM;
        }
    case CTC_ACL_KEY_HASH_NSH:
        if(DRV_FROM_AT(lchip) && SYS_ACL_IS_GLOBAL_PP_EN_LKUP(lchip, pg->group_info.dir, pg->group_info.block_id)
                              && CTC_ACL_GROUP_TYPE_HASH != pg->group_info.type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Priority 0 Global ACL Enable, flow hash must assign group type CTC_ACL_GROUP_TYPE_HASH\n");
            return CTC_E_INVALID_PARAM;
        }
        break;

    case CTC_ACL_KEY_PBR_IPV4:
    case CTC_ACL_KEY_PBR_IPV6:
    case CTC_ACL_KEY_MPLS:
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " API or some feature is not supported \n");
			return CTC_E_NOT_SUPPORT;
    default:
        break;

    }
    return CTC_E_NONE;
}

/*
  ad_type:  0-DsAcl, 1-DsFlow
*/
int32
_sys_usw_acl_bind_nexthop(uint8 lchip, sys_acl_entry_t* pe,uint32 nh_id,uint8 ad_type)
{
    sys_acl_hash_entry_t* pe_hash = ACL_SHARE_PTR(pe, sys_acl_hash_entry_t);
    sys_nh_update_dsnh_param_t update_dsnh;
	int32 ret = 0;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
     sal_memset(&update_dsnh, 0, sizeof(sys_nh_update_dsnh_param_t));

    /* nh don't use dsfwd, need bind nh and dsacl */
    update_dsnh.data = pe;
    update_dsnh.updateAd = ad_type?_sys_usw_acl_update_dsflow_action:_sys_usw_acl_update_action;
    update_dsnh.chk_data = ad_type?pe_hash->entry_id:pe->fpae.entry_id;
    update_dsnh.bind_feature = CTC_FEATURE_ACL;
    ret = sys_usw_nh_bind_dsfwd_cb(lchip, nh_id, &update_dsnh);
    if(CTC_E_NONE == ret)
    {
       /*MergeDsFwd Mode need bind ad and nh*/
       pe->bind_nh  = 1;
    }
    return ret;
}

int32
_sys_usw_acl_unbind_nexthop(uint8 lchip, sys_acl_entry_t* pe)
{
    sys_acl_hash_entry_t* pe_hash = ACL_SHARE_PTR(pe, sys_acl_hash_entry_t);
    uint32 nhid = 0;
    //uint16 action_flag = 0;
    if (ACL_ENTRY_IS_TCAM(pe))
    {
        //action_flag = pe->ua->buffer.ad.tcam.action_flag;
        nhid = pe->ua->buffer.ad.tcam.nexthop_id;
    }
    else
    {
        //action_flag = pe_hash->ua->buffer.ad.hash.action_flag;
        nhid = pe_hash->ua->buffer.ad.hash.nexthop_id;
    }
    if (1 == pe->bind_nh && nhid)
    {
        sys_nh_update_dsnh_param_t update_dsnh;
        update_dsnh.data = NULL;
        update_dsnh.updateAd = NULL;
        sys_usw_nh_bind_dsfwd_cb(lchip, nhid, &update_dsnh);
        pe->bind_nh = 0;
    }
    /*if (ACL_ENTRY_IS_TCAM(pe))
    {
        pe->ua->buffer.ad.tcam.action_flag = action_flag;
    }
    else
    {
        pe_hash->ua->buffer.ad.hash.action_flag = action_flag;
    }*/

    return CTC_E_NONE;
}

int32
_sys_usw_acl_check_discard_type(uint8 discard_type)
{
    /* not support discard_type which exist after acl process:
            IPEDISCARDTYPE_UC_TO_LAG_GROUP_NO_MEMBER          0x3
            IPEDISCARDTYPE_MICROFLOW_POLICING_FAIL_DROP       0x7
            IPEDISCARDTYPE_STACK_REFLECT_DISCARD              0xd
            IPEDISCARDTYPE_STORM_CTL_DIS                      0x14
            IPEDISCARDTYPE_NO_FORWARDING_PTR                  0x16
            IPEDISCARDTYPE_DS_PLC_DIS                          0x2c
            IPEDISCARDTYPE_DS_ACL_DIS                          0x2d
            IPEDISCARDTYPE_CFLAX_SRC_ISOLATE_DIS              0x31
            IPEDISCARDTYPE_SD_CHECK_DIS                          0x3f
    */
    if ((discard_type >= 0x3f) || (0x3 == discard_type) || (0x7 == discard_type) || (0xd == discard_type)
        || (0x14 == discard_type) || (0x16 == discard_type) || (0x2c == discard_type) || (0x2d == discard_type)
        || (0x31 == discard_type))
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_check_tcam_key_param(uint8 lchip, ctc_field_key_t* key_field, sys_acl_entry_t* pe, uint8 is_add)
{
    uint8 copp_key = 0;
    uint8 copp_ext_key = 0;
    uint8 copp_basic_key = 0;
    uint8 discard_type = 0;
    uint8 tmp_l3_type = 0;
    uint8 key_type = sys_usw_acl_get_origin_key_type(lchip, pe);

    copp_ext_key = key_type == CTC_ACL_KEY_COPP_EXT;
    copp_basic_key = key_type == CTC_ACL_KEY_COPP;
    copp_key = copp_basic_key || copp_ext_key;

    switch(key_field->type)
    {
    case CTC_FIELD_KEY_GRE_FLAGS:
    case CTC_FIELD_KEY_GRE_PROTOCOL_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_FID:
        CTC_MAX_VALUE_CHECK(key_field->data, MCHIP_CAP(SYS_CAP_FID_NUM));
        break;
    case CTC_FIELD_KEY_METADATA:
        SYS_ACL_METADATA_CHECK(pe->group->group_info.type);
        SYS_USW_METADATE_CHECK(key_field->data);
        break;
    case CTC_FIELD_KEY_SRC_CID:
    case CTC_FIELD_KEY_DST_CID:
        CTC_MAX_VALUE_CHECK(key_field->data, MCHIP_CAP(SYS_CAP_ACL_MAX_CID_VALUE));
        break;
    case CTC_FIELD_KEY_SVLAN_ID:
    case CTC_FIELD_KEY_CVLAN_ID:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFF);
        break;
    case CTC_FIELD_KEY_STAG_COS:
    case CTC_FIELD_KEY_CTAG_COS:
        CTC_MAX_VALUE_CHECK(key_field->data, 7);
        break;
    case CTC_FIELD_KEY_STAG_CFI:
    case CTC_FIELD_KEY_CTAG_CFI:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_L2_TYPE:
    case CTC_FIELD_KEY_VLAN_NUM:
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        break;
    case CTC_FIELD_KEY_L3_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_L4_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_L4_USER_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_IPV6_FLOW_LABEL:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFF);
        break;
    case CTC_FIELD_KEY_IP_TTL:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_IP_DSCP:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        break;
    case CTC_FIELD_KEY_IP_PROTOCOL:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_IP_PRECEDENCE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x7);
        break;
    case CTC_FIELD_KEY_IP_ECN:
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        break;
    case CTC_FIELD_KEY_IP_FRAG:
        if (((DRV_IS_TSINGMA(lchip) && (key_type == CTC_ACL_KEY_COPP || key_type == CTC_ACL_KEY_UDF)) ||
            (DRV_FROM_TMM(lchip) && (key_type == CTC_ACL_KEY_IPV4 || key_type == CTC_ACL_KEY_IPV6))) &&
            !(CTC_IP_FRAG_NON == key_field->data || CTC_IP_FRAG_YES == key_field->data))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Ip frag only support none and yes\n");
            return CTC_E_NOT_SUPPORT;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, CTC_IP_FRAG_MAX-1);
        break;
    case CTC_FIELD_KEY_IP_HDR_ERROR:
    case CTC_FIELD_KEY_IP_OPTIONS:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_L4_DST_PORT:
    case CTC_FIELD_KEY_L4_SRC_PORT:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_TCP_ECN:
        if (key_type == CTC_ACL_KEY_IPV4 || key_type == CTC_ACL_KEY_CID)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x3);/* 2bit */
        }
        else
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x7);/* 3bit */
        }
        break;
    case CTC_FIELD_KEY_TCP_FLAGS:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        break;
    case CTC_FIELD_KEY_ICMP_CODE:
    case CTC_FIELD_KEY_ICMP_TYPE:
    case CTC_FIELD_KEY_IGMP_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_VXLAN_RSV1:
    case CTC_FIELD_KEY_VN_ID:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_VXLAN_FLAGS:
    case CTC_FIELD_KEY_VXLAN_RSV2:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_NVGRE_KEY:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_ARP_OP_CODE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_ARP_PROTOCOL_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_ARP_MAC_DA_CHK_FAIL:
    case CTC_FIELD_KEY_ARP_MAC_SA_CHK_FAIL:
    case CTC_FIELD_KEY_ARP_SENDERIP_CHK_FAIL:
    case CTC_FIELD_KEY_ARP_TARGETIP_CHK_FAIL:
    case CTC_FIELD_KEY_GARP:
    case CTC_FIELD_KEY_RARP:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_LABEL_NUM:
        CTC_MAX_VALUE_CHECK(key_field->data, MCHIP_CAP(SYS_CAP_ACL_LABEL_NUM));
        break;
    case CTC_FIELD_KEY_MPLS_LABEL0:
    case CTC_FIELD_KEY_MPLS_LABEL1:
    case CTC_FIELD_KEY_MPLS_LABEL2:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFF);
        break;
    case CTC_FIELD_KEY_MPLS_EXP0:
    case CTC_FIELD_KEY_MPLS_EXP1:
    case CTC_FIELD_KEY_MPLS_EXP2:
        CTC_MAX_VALUE_CHECK(key_field->data, 7);
        break;
    case CTC_FIELD_KEY_MPLS_SBIT0:
    case CTC_FIELD_KEY_MPLS_SBIT1:
    case CTC_FIELD_KEY_MPLS_SBIT2:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_MPLS_TTL0:
    case CTC_FIELD_KEY_MPLS_TTL1:
    case CTC_FIELD_KEY_MPLS_TTL2:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_INTERFACE_ID:
        if (!DRV_FROM_TMM(lchip) && (key_type == CTC_ACL_KEY_IPV4_EXT || key_type == CTC_ACL_KEY_MAC_IPV4) &&
            (CTC_PARSER_L3_TYPE_MPLS != pe->l3_type) && (CTC_PARSER_L3_TYPE_MPLS_MCAST!=pe->l3_type)
            && !CTC_FLAG_ISSET(pe->flag, SYS_ACL_ENTRY_FLAG_Y1731))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "when l3_key or mac_l3_key use interface id ,the pkt must be mpls or ether_oam:%d\n", pe->l3_type);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, (MCHIP_CAP(SYS_CAP_SPEC_L3IF_NUM)-1));/*10bit; 1023 is reserved*/
        break;
    case CTC_FIELD_KEY_NSH_CBIT:
    case CTC_FIELD_KEY_NSH_OBIT:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x1);
        break;
    case CTC_FIELD_KEY_NSH_NEXT_PROTOCOL:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_NSH_SI:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_NSH_SPI:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_IS_Y1731_OAM:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x1);
        break;
    case CTC_FIELD_KEY_ETHER_OAM_LEVEL:
        CTC_MAX_VALUE_CHECK(key_field->data, 7);
        break;
    case CTC_FIELD_KEY_ETHER_OAM_OP_CODE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_ETHER_OAM_VERSION:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x1F);
        break;
    case CTC_FIELD_KEY_SLOW_PROTOCOL_CODE:
    case CTC_FIELD_KEY_SLOW_PROTOCOL_SUB_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_SLOW_PROTOCOL_FLAGS:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_PTP_MESSAGE_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_PTP_VERSION:
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        break;
    case CTC_FIELD_KEY_FCOE_DST_FCID:
    case CTC_FIELD_KEY_FCOE_SRC_FCID:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_INGRESS_NICKNAME:
    case CTC_FIELD_KEY_EGRESS_NICKNAME:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_IS_ESADI:
    case CTC_FIELD_KEY_IS_TRILL_CHANNEL:
    case CTC_FIELD_KEY_TRILL_MULTIHOP:
    case CTC_FIELD_KEY_TRILL_MULTICAST:
    case CTC_FIELD_KEY_TRILL_INNER_VLANID_VALID:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_TRILL_INNER_VLANID:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFF);
        break;
    case CTC_FIELD_KEY_TRILL_LENGTH:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x3FFF);
        break;
    case CTC_FIELD_KEY_TRILL_VERSION:
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        break;
    case CTC_FIELD_KEY_TRILL_TTL:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        break;
    case CTC_FIELD_KEY_DOT1AE_UNKNOW_PKT:
    case CTC_FIELD_KEY_DOT1AE_ES:
    case CTC_FIELD_KEY_DOT1AE_SC:
    case CTC_FIELD_KEY_DOT1AE_CBIT:
    case CTC_FIELD_KEY_DOT1AE_EBIT:
    case CTC_FIELD_KEY_DOT1AE_SCB:
    case CTC_FIELD_KEY_DOT1AE_VER:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_DOT1AE_AN:
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        break;
    case CTC_FIELD_KEY_DOT1AE_SL:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        break;
    case CTC_FIELD_KEY_SATPDU_MEF_OUI:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_SATPDU_OUI_SUB_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_WLAN_RADIO_ID:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x1F);
        break;
    case CTC_FIELD_KEY_WLAN_CTL_PKT:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_VRFID:
        SYS_IP_VRFID_CHECK(key_field->data);
        break;
    case CTC_FIELD_KEY_DECAP:
    case CTC_FIELD_KEY_ELEPHANT_PKT:
    case CTC_FIELD_KEY_VXLAN_PKT:
    case CTC_FIELD_KEY_ROUTED_PKT:
    case CTC_FIELD_KEY_MACSA_HIT:
    case CTC_FIELD_KEY_MACDA_HIT:
    case CTC_FIELD_KEY_IPSA_HIT:
    case CTC_FIELD_KEY_IPSA_LKUP:
    case CTC_FIELD_KEY_IPDA_LKUP:
    case CTC_FIELD_KEY_IPDA_HIT:
    case CTC_FIELD_KEY_MACSA_LKUP:
    case CTC_FIELD_KEY_MACDA_LKUP:
    case CTC_FIELD_KEY_L2_STATION_MOVE:
    case CTC_FIELD_KEY_MAC_SECURITY_DISCARD:
    case CTC_FIELD_KEY_MCAST_RPF_CHECK_FAIL:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_PKT_FWD_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_CPU_REASON_ID:
        CTC_MAX_VALUE_CHECK(key_field->data, NULL == key_field->ext_data ? CTC_PKT_CPU_REASON_MAX_COUNT : SYS_USW_ACL_MATCH_GRP_MAX_COUNT);
        break;
    case CTC_FIELD_KEY_DST_GPORT:
        SYS_GLOBAL_PORT_CHECK(key_field->data);
        break;
    case CTC_FIELD_KEY_DST_NHID:
        if (key_field->ext_data && (0 == key_field->data) && (0 == key_field->mask))
        {
            uint32 dsnh_num = 0;
            sys_usw_ftm_query_table_entry_num(lchip, DsNextHop4W_t, &dsnh_num);
            CTC_MAX_VALUE_CHECK(*(uint32*)key_field->ext_data, dsnh_num-1);
        }
        break;
    case CTC_FIELD_KEY_STP_STATE:
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        key_field->mask = 0x3;
        if(2 == key_field->data)
        {
            key_field->data = 3;
        }
        else if(3 == key_field->data)
        {
            key_field->data = 1;
            key_field->mask = 0x1;
        }
        break;
    case CTC_FIELD_KEY_MAC_SA:
    case CTC_FIELD_KEY_MAC_DA:
    case CTC_FIELD_KEY_SENDER_MAC:
    case CTC_FIELD_KEY_TARGET_MAC:
    case CTC_FIELD_KEY_WLAN_RADIO_MAC:
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
        break;
    case CTC_FIELD_KEY_SVLAN_RANGE:
    case CTC_FIELD_KEY_CVLAN_RANGE:
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_MAX_VALUE_CHECK(key_field->data, key_field->mask);
            SYS_ACL_VLAN_ID_CHECK(key_field->mask);
        }
        break;
    case CTC_FIELD_KEY_IPV6_SA:
    case CTC_FIELD_KEY_IPV6_DA:
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
        break;
    case CTC_FIELD_KEY_SATPDU_PDU_BYTE:
    case CTC_FIELD_KEY_DOT1AE_SCI:
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
        break;
    case CTC_FIELD_KEY_UDF:
    case CTC_FIELD_KEY_UDF_AD_ID:
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
        break;
    case CTC_FIELD_KEY_PORT:
        if(is_add)
        {
            ctc_field_port_t* p_field_port = (ctc_field_port_t*)key_field->ext_data;
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            if(copp_key && \
                (CTC_FIELD_PORT_TYPE_NONE != p_field_port->type) && (CTC_FIELD_PORT_TYPE_PORT_BITMAP !=p_field_port->type))
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The key port type must be none or bitmap, key_port_type:%d\n", p_field_port->type);
                return CTC_E_NOT_SUPPORT;
            }
            if((key_type == CTC_ACL_KEY_CID) && \
                (CTC_FIELD_PORT_TYPE_GPORT==p_field_port->type || CTC_FIELD_PORT_TYPE_LOGIC_PORT==p_field_port->type || CTC_FIELD_PORT_TYPE_PORT_BITMAP==p_field_port->type ))
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The key port type must not be gport ,logical port por bitmap, key_port_type:%d\n", p_field_port->type);
                return CTC_E_NOT_SUPPORT;
            }
            if (key_type == CTC_ACL_KEY_UDF && CTC_FIELD_PORT_TYPE_GPORT == p_field_port->type)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The key port type must not be gport, key_port_type:%d\n", p_field_port->type);
                return CTC_E_NOT_SUPPORT;
            }
            CTC_ERROR_RETURN(_sys_usw_acl_check_port_info(lchip, pe, key_field));
        }
        break;
    case CTC_FIELD_KEY_AWARE_TUNNEL_INFO:
        if(is_add)
        {
            ctc_acl_tunnel_data_t* p_tunnel_data = (ctc_acl_tunnel_data_t*)key_field->ext_data;
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->type, 0x03);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->vxlan_vni, 0xFFFFFF);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->radio_id, 0x1F);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->wlan_ctl_pkt, 0x01);
        }
        break;
    case CTC_FIELD_KEY_DISCARD:
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        if(is_add && (key_field->ext_data) && (key_type == CTC_ACL_KEY_FWD || key_type == CTC_ACL_KEY_FWD_EXT || copp_key))
        {
            discard_type = *((uint32*)(key_field->ext_data));
            CTC_ERROR_RETURN(_sys_usw_acl_check_discard_type(discard_type));
        }
        break;
    case CTC_FIELD_KEY_CLASS_ID:
        if(is_add)
        {
            SYS_USW_CLASS_ID_RANGE_CHECK(key_field->data);
        }
        break;
    case CTC_FIELD_KEY_PRIORITY:
        if (DRV_FROM_TMM(lchip))
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        }
        break;
    case CTC_FIELD_KEY_ETHER_TYPE:
        if (key_type != CTC_ACL_KEY_MAC && key_type != CTC_ACL_KEY_UDF)
        {
            _sys_usw_acl_map_ethertype(key_field->data, &tmp_l3_type);
            if (tmp_l3_type != CTC_PARSER_L3_TYPE_NONE)
            {
                key_field->type = CTC_FIELD_KEY_L3_TYPE;
                key_field->data = tmp_l3_type;
                key_field->mask = 0xF;
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Key filed:%s (EthType:0x%x) mapping to %s (l3_type:%d)n", "CTC_FIELD_KEY_ETHER_TYPE", key_field->data, \
                "CTC_FIELD_KEY_L3_TYPE", tmp_l3_type);
            }
            else if (key_type == CTC_ACL_KEY_FWD  || key_type == CTC_ACL_KEY_FWD_EXT  ||
                     key_type == CTC_ACL_KEY_IPV4 || key_type == CTC_ACL_KEY_IPV4_EXT ||
                     key_type == CTC_ACL_KEY_MAC_IPV4 || key_type == CTC_ACL_KEY_MAC_IPV4_EXT)
            {
                ctc_field_key_t key_field_temp = {0};
                key_field_temp.type = CTC_FIELD_KEY_L3_TYPE;
                key_field_temp.data = CTC_PARSER_L3_TYPE_NONE;
                key_field_temp.mask = 0xF;
                if(p_usw_acl_master[lchip]->build_key_func[key_type])
                {
                    CTC_ERROR_RETURN(p_usw_acl_master[lchip]->build_key_func[key_type](lchip, &key_field_temp, pe, is_add));
                }
            }
        }
        break;
    case CTC_FIELD_KEY_NPM_IM_FLOW_ID:
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFF);
        break;
    case CTC_FIELD_KEY_NPM_IM_L_FLAG:
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    default:
        break;
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_check_tcam_key_union(uint8 lchip, ctc_field_key_t* key_field, sys_acl_entry_t* pe, uint8 is_add)
{
    uint8 step = 0;
    uint8 dir = pe->group->group_info.dir;
    uint32 cmd = 0;
    IpePreLookupAclCtl_m ipe_pre_lkup_ctl;
    EpePktProcCtl_m      epe_pkt_proc_ctl;
    ds_t   ds;
    ctc_global_acl_property_t glb_acl_prop;
    uint8 l3_key_share_field_mode;
    uint8 key_port_is_cid = 0 ;
    uint8 cid_key_v6_use_ipda = 0;
    uint8 cid_key = 0;
    uint8 copp_key = 0;
    uint8 copp_ext_key = 0;
    uint8 copp_basic_key = 0;
    uint8 copp_key_use_ctag = 0;
    uint8 copp_key_use_l3l4_type = 0;
    uint8 copp_basic_key_ipaddr_use_ipsa = 0;
    uint8 copp_ext_key_ipv6sa =0;
    uint8 fwd_ext_key = 0;
    uint8 fwd_ext_key_use_l2_hdr = 0;
    uint8 fwd_ext_key_udf_use_nsh = 0;
    uint8 arware_tunnel_info = 0;
    uint8 l3_key = 0;
    uint8 mac_key = 0;
    uint8 short_key = 0;
    uint8 short_key_use_svlan = 0;
    uint8 fwd_key = 0;
    uint8 l3_ext_key = 0;
    uint8 mac_l3_key = 0;
    uint8 mac_l3_ext_key = 0;
    uint8 mac_ipv6_key = 0;
    uint8 udf_key = 0;
    uint8 ipv6_key = 0;
    uint8 ipv6_ext_key = 0;
    uint8 mac_l3_ext_key_mac_da_mode = 0;
    uint8 mac_l3_ext_key_mac_sa_mode = 0;
    uint8 mac_l3_key_mac_sa_mode = 0;
    uint8 mac_l3_key_mac_da_mode = 0;
    uint8 l2type_use_vlanNum = 0;
    uint8 l3_type = pe->l3_type;
    uint8 l4_type = pe->l4_type;
    uint8 l4_user_type = pe->l4_user_type;
    uint8 copp_key_basic_mac_da_mode = 0;
    uint8  discard_type = 0;
    uint8 xgpon_use_gem_port = 0;
    uint8 service_queue_egress_en = 0;
    uint8 copp_key_use_udf = 0;
    uint8 copp_ext_key_use_udf = 0;
    uint8 set_l3_mask = 0;
    uint8 support_vsi_check = 0;

    sal_memset(&glb_acl_prop, 0, sizeof(ctc_global_acl_property_t));
    cmd = DRV_IOR(IpeAclQosCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), ds);
    xgpon_use_gem_port = GetIpeAclQosCtl(V, useGemPortLookup_f, ds);

    cmd = DRV_IOR(FlowTcamLookupCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), ds);

    if (CTC_INGRESS == pe->group->group_info.dir)
    {
        step = FlowTcamLookupCtl_gIngrAcl_1_categoryIdFieldValid_f - FlowTcamLookupCtl_gIngrAcl_0_categoryIdFieldValid_f;
        key_port_is_cid = GetFlowTcamLookupCtl(V, gIngrAcl_0_categoryIdFieldValid_f + step *  pe->group->group_info.block_id, ds);
        cid_key_v6_use_ipda = GetFlowTcamLookupCtl(V, ingrSgaclKeyIpv6PktUseIpDaField_f, ds);
        if (pe->key_type == CTC_ACL_KEY_COPP)
        {
            copp_key_use_ctag = GetFlowTcamLookupCtl(V, coppBasicKeyUseCtag_f, ds);
            copp_key_use_l3l4_type = GetFlowTcamLookupCtl(V, coppBasicKeyEtherTypeShareType_f, ds);/*default to 1*/
            copp_basic_key_ipaddr_use_ipsa = GetFlowTcamLookupCtl(V, coppKeyIpAddrShareType0_f, ds); /*default to 0*/
            copp_key_use_udf = GetFlowTcamLookupCtl(V, coppBasicKeyUseUdfShareType_f, ds) & 1;
        }
        if (pe->key_type == CTC_ACL_KEY_COPP_EXT)
        {
            copp_key_use_ctag = GetFlowTcamLookupCtl(V, coppExtKeyUseCtag_f, ds);
            copp_key_use_l3l4_type = GetFlowTcamLookupCtl(V, coppExtKeyEtherTypeShareType_f, ds);/*default to 1*/
            copp_ext_key_ipv6sa = 1 & GetFlowTcamLookupCtl(V, coppKeyIpAddrShareType0_f, ds); /*default to 1*/
            copp_ext_key_use_udf =  GetFlowTcamLookupCtl(V, coppExtKeyUdfShareType_f,ds)?0:1;
        }
        step = FlowTcamLookupCtl_gIngrAcl_1_l3Key160ShareFieldType_f - FlowTcamLookupCtl_gIngrAcl_0_l3Key160ShareFieldType_f;
        l3_key_share_field_mode = GetFlowTcamLookupCtl(V,gIngrAcl_0_l3Key160ShareFieldType_f + step * pe->group->group_info.block_id, ds);

        cmd = DRV_IOR(IpePreLookupAclCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ipe_pre_lkup_ctl);
        l2type_use_vlanNum = GetIpePreLookupAclCtl(V, layer2TypeUsedAsVlanNum_f, &ipe_pre_lkup_ctl);
    }
    else
    {
        cid_key_v6_use_ipda = GetFlowTcamLookupCtl(V, egrSgaclKeyIpv6PktUseIpDaField_f, ds);
        glb_acl_prop.dir = CTC_EGRESS;
		glb_acl_prop.lkup_level = pe->group->group_info.block_id;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &glb_acl_prop, 1));
        key_port_is_cid = glb_acl_prop.key_cid_en;

        step = FlowTcamLookupCtl_gEgrAcl_1_l3Key160ShareFieldType_f - FlowTcamLookupCtl_gEgrAcl_0_l3Key160ShareFieldType_f;
        l3_key_share_field_mode = GetFlowTcamLookupCtl(V,gEgrAcl_0_l3Key160ShareFieldType_f + step * pe->group->group_info.block_id, ds);

        cmd = DRV_IOR(EpePktProcCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &epe_pkt_proc_ctl);
        l2type_use_vlanNum = GetEpePktProcCtl(V, layer2TypeUsedAsVlanNum_f, &epe_pkt_proc_ctl);
    }

    l3_key_share_field_mode = GetFlowTcamLookupCtl(V,gIngrAcl_0_l3Key160ShareFieldType_f,ds);
    arware_tunnel_info = !GetFlowTcamLookupCtl(V,array_0_ignorMergeMode_f,ds);

    fwd_ext_key_use_l2_hdr = !(GetFlowTcamLookupCtl(V,forwardingAclKeyUnion1Type_f,ds) & (1 << (pe->group->group_info.block_id &0x7)));
    fwd_ext_key_udf_use_nsh = GetFlowTcamLookupCtl(V,forceForwardingAclKeyUseNsh_f,ds) & (1 << (pe->group->group_info.block_id&0x7));
    short_key_use_svlan =  !GetFlowTcamLookupCtl(V,acl80bitKeyUseCvlan_f,ds);

    if (DRV_FROM_TMM(lchip))
    {
        mac_l3_ext_key_mac_sa_mode = GetFlowTcamLookupCtl(V,aclMacL3ExtKeyArpPktUseMacField_f,ds) & 1;
        mac_l3_ext_key_mac_da_mode= GetFlowTcamLookupCtl(V,aclMacL3ExtKeyArpPktUseMacField_f,ds) >> 1;
        mac_l3_key_mac_sa_mode = GetFlowTcamLookupCtl(V,aclMacL3BasicKeyArpPktUseMacField_f,ds) & 1;
        mac_l3_key_mac_da_mode = GetFlowTcamLookupCtl(V,aclMacL3BasicKeyArpPktUseMacField_f,ds) >> 1;
    }
    else
    {
        mac_l3_ext_key_mac_sa_mode = GetFlowTcamLookupCtl(V,aclMacL3ExtKeyArpPktUseSenderMac_f,ds);
        mac_l3_ext_key_mac_da_mode= GetFlowTcamLookupCtl(V,aclMacL3ExtKeyArpPktUseTargetMac_f,ds);
        mac_l3_key_mac_sa_mode = GetFlowTcamLookupCtl(V,aclMacL3BasicKeyArpPktUseSenderMac_f,ds);
        mac_l3_key_mac_da_mode = GetFlowTcamLookupCtl(V,aclMacL3BasicKeyArpPktUseTargetMac_f,ds);
    }
    copp_key_basic_mac_da_mode = !GetFlowTcamLookupCtl(V,coppBasicKeyDisableArpShareMacDa_f,ds);

    cid_key = pe->key_type == CTC_ACL_KEY_CID;
    copp_ext_key = pe->key_type == CTC_ACL_KEY_COPP_EXT;
    copp_basic_key = pe->key_type == CTC_ACL_KEY_COPP;
    copp_key = copp_basic_key || copp_ext_key;
    fwd_ext_key =  pe->key_type == CTC_ACL_KEY_FWD_EXT;
    fwd_key =  pe->key_type == CTC_ACL_KEY_FWD;
    l3_key = pe->key_type == CTC_ACL_KEY_IPV4;
    mac_key = pe->key_type == CTC_ACL_KEY_MAC;
    l3_ext_key = pe->key_type == CTC_ACL_KEY_IPV4_EXT;
    mac_l3_key = pe->key_type == CTC_ACL_KEY_MAC_IPV4;
    mac_l3_ext_key = pe->key_type == CTC_ACL_KEY_MAC_IPV4_EXT;
    mac_ipv6_key = pe->key_type == CTC_ACL_KEY_MAC_IPV6;
    short_key = pe->key_type == CTC_ACL_KEY_INTERFACE;
    udf_key = pe->key_type == CTC_ACL_KEY_UDF;
    ipv6_key = pe->key_type == CTC_ACL_KEY_IPV6;
    ipv6_ext_key = pe->key_type == CTC_ACL_KEY_IPV6_EXT;

    if ((key_field->type == CTC_FIELD_KEY_ETHER_TYPE) && (CTC_ACL_KEY_MAC != pe->key_type)&&(CTC_ACL_KEY_UDF != pe->key_type))
    {
        uint8 tmp_l3_type = 0;
        _sys_usw_acl_map_ethertype(key_field->data, &tmp_l3_type);
        if (tmp_l3_type != CTC_PARSER_L3_TYPE_NONE)
        {
            key_field->type = CTC_FIELD_KEY_L3_TYPE;
            key_field->data = tmp_l3_type;
            key_field->mask = 0xF;
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Key filed:%s (EthType:0x%x) mapping to %s (l3_type:%d)n", "CTC_FIELD_KEY_ETHER_TYPE", key_field->data, \
            "CTC_FIELD_KEY_L3_TYPE", tmp_l3_type);
        }
        else
        {
            set_l3_mask = 1;
        }
    }

    if (!key_field->ext_data)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Key filed:%d,keyData:%d\n", key_field->type, key_field->data)
    }
    else
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Key filed:%d ", key_field->type)
    }
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "l2_type:%d l3_type:%d l4_type:%d,l4 userType:%d \n", pe->l2_type, pe->l3_type, pe->l4_type, pe->l4_user_type);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mac_l3_key_mac_sa_mode:%d, mac_l3_key_mac_da_mode:%d \n", mac_l3_key_mac_sa_mode, mac_l3_key_mac_da_mode);

    support_vsi_check = (SYS_GET_CHIP_VERSION != SYS_CHIP_SUB_VERSION_A && DRV_IS_TSINGMA(lchip)) ? 1 : 0;

    switch(key_field->type)
    {
    case CTC_FIELD_KEY_GRE_FLAGS:
    case CTC_FIELD_KEY_GRE_PROTOCOL_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_FID:
        CTC_MAX_VALUE_CHECK(key_field->data, MCHIP_CAP(SYS_CAP_FID_NUM));
        if(!support_vsi_check)
        {
            break;
        }
        if ((pe->key_type == CTC_ACL_KEY_COPP && 0 == GetFlowTcamLookupCtl(V, coppBasicKeySupportVsi_f, ds))
            || (pe->key_type == CTC_ACL_KEY_COPP_EXT && 0 == GetFlowTcamLookupCtl(V, coppExtKeySupportVsi_f, ds)))
        {
            return CTC_E_NOT_SUPPORT;
        }
        if ((pe->key_type == CTC_ACL_KEY_FWD && 0 == GetFlowTcamLookupCtl(V, forwardingBasicKeySupportVsi_f, ds))
            || (pe->key_type == CTC_ACL_KEY_FWD_EXT && 0 == GetFlowTcamLookupCtl(V, forwardingExtKeySupportVsi_f, ds)))
        {
            return CTC_E_NOT_SUPPORT;
        }
        if ((pe->key_type == CTC_ACL_KEY_MAC_IPV4) || (pe->key_type == CTC_ACL_KEY_MAC_IPV6))
        {
            uint8 step = FlowTcamLookupCtl_gIngrAcl_1_aclL2L3KeySupportVsi_f - FlowTcamLookupCtl_gIngrAcl_0_aclL2L3KeySupportVsi_f;
            if (0 == GetFlowTcamLookupCtl(V, gIngrAcl_0_aclL2L3KeySupportVsi_f + step * pe->group->group_info.block_id , ds))
            {
                return CTC_E_NOT_SUPPORT;
            }
        }
        break;
    case CTC_FIELD_KEY_PORT:
        if (pe->key_port_mode == 2)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Key Port check conflict,key_port_mode:%d \n", pe->key_port_mode);
            return CTC_E_PARAM_CONFLICT;
        }
        break;
    case CTC_FIELD_KEY_GEM_PORT:
        if ((!xgpon_use_gem_port) || DRV_IS_DUET2(lchip) || DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Gem port not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_FIELD_KEY_METADATA:
        if (DRV_FROM_TMM(lchip) && !mac_l3_ext_key && !mac_l3_key && !mac_ipv6_key && dir == CTC_EGRESS)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Metadata not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if (((pe->key_port_mode == 1) || key_port_is_cid) && !DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Key Port check conflict,key_port_mode:%d key_is_cid:%d \n", pe->key_port_mode, key_port_is_cid);
            return CTC_E_PARAM_CONFLICT;
        }
        SYS_ACL_METADATA_CHECK(pe->group->group_info.type);
        SYS_USW_METADATE_CHECK(key_field->data);
        break;
    case CTC_FIELD_KEY_SRC_CID:
        if (!cid_key &&((pe->key_port_mode == 1) || !key_port_is_cid)&&!DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Key Port check conflict,key_port_mode:%d key_is_cid:%d \n", pe->key_port_mode, key_port_is_cid);
            return CTC_E_INVALID_PARAM;
        }
		CTC_MAX_VALUE_CHECK(key_field->data, MCHIP_CAP(SYS_CAP_ACL_MAX_CID_VALUE));
        CTC_ERROR_RETURN(sys_usw_global_get_logic_destport_en(lchip,&service_queue_egress_en));
        if(pe->group->group_info.dir == CTC_EGRESS && service_queue_egress_en)
        {
            return CTC_E_NOT_SUPPORT;
        }
        break;
    case CTC_FIELD_KEY_DST_CID:
        if (!cid_key && ((pe->key_port_mode == 1) || !key_port_is_cid)&&!DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Key Port check conflict,key_port_mode:%d key_is_cid:%d \n", pe->key_port_mode, key_port_is_cid);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, MCHIP_CAP(SYS_CAP_ACL_MAX_CID_VALUE));
        break;
    case CTC_FIELD_KEY_MAC_SA:                   /**< [D2] Source MAC Address. */
    case CTC_FIELD_KEY_MAC_DA:                  /**< [D2] Destination MAC Address. */
        if (fwd_ext_key && !fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d \n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_ext_key
            && key_field->type == CTC_FIELD_KEY_MAC_SA
        && (l3_type  == CTC_PARSER_L3_TYPE_ARP)
        && mac_l3_ext_key_mac_sa_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_ext_key mac_sa_mode:%d \n", mac_l3_ext_key_mac_sa_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key
            && key_field->type == CTC_FIELD_KEY_MAC_SA
        && (l3_type  == CTC_PARSER_L3_TYPE_ARP)
        && mac_l3_key_mac_sa_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_key mac_sa_mode:%d \n", mac_l3_key_mac_sa_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key
            && key_field->type == CTC_FIELD_KEY_MAC_DA
        && (l3_type  == CTC_PARSER_L3_TYPE_ARP)
        && mac_l3_key_mac_da_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_key mac_da_mode:%d \n", mac_l3_key_mac_da_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (copp_basic_key
            && key_field->type == CTC_FIELD_KEY_MAC_DA
        && (l3_type  == CTC_PARSER_L3_TYPE_ARP)
        && copp_key_basic_mac_da_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp_key mac_sa_mode:%d \n", copp_key_basic_mac_da_mode);
            return CTC_E_INVALID_PARAM;
        }

        if (mac_l3_ext_key
            && key_field->type == CTC_FIELD_KEY_MAC_DA
        && (l3_type  == CTC_PARSER_L3_TYPE_ARP)
        && mac_l3_ext_key_mac_da_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_ext_key mac_da_mode:%d \n", mac_l3_ext_key_mac_da_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key
            && key_field->type == CTC_FIELD_KEY_MAC_DA
            && pe->macl3basic_key_macda_mode == 2)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_basic_key mac_da_mode:%d \n", pe->macl3basic_key_macda_mode);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_STAG_VALID:               /**< [D2] S-Vlan Exist. */
    case CTC_FIELD_KEY_SVLAN_ID:                 /**< [D2] S-Vlan ID. */
    case CTC_FIELD_KEY_STAG_COS:                 /**< [D2] Stag Cos. */
    case CTC_FIELD_KEY_STAG_CFI:                 /**< [D2] Stag Cfi. */
    case CTC_FIELD_KEY_SVLAN_RANGE:              /**< [D2] Svlan Range;
        data: min, mask: max, ext_data: (uint32*)vrange_gid. */
        if (copp_key && copp_key_use_ctag)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp_key copp_key_use_ctag:%d \n", copp_key_use_ctag);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && !fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d \n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_key && (pe->mac_key_vlan_mode == 2))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac key vlan_mode:%d \n", pe->mac_key_vlan_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (short_key && !short_key_use_svlan)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "interface key use_svlan:%d \n", short_key_use_svlan);
            return CTC_E_INVALID_PARAM;
        }
        if(fwd_key && GetFlowTcamLookupCtl(V,aclForwardingBasicKeyUseCvlan_f,ds))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "forward key in use cvlan mode\n");
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_SVLAN_ID)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_STAG_COS)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 7);
        }
        if (key_field->type == CTC_FIELD_KEY_STAG_CFI)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;

    case CTC_FIELD_KEY_CVLAN_ID:                 /**< [D2] C-Vlan ID. */
    case CTC_FIELD_KEY_CTAG_COS:                 /**< [D2] Ctag Cos. */
    case CTC_FIELD_KEY_CVLAN_RANGE:              /**< [D2] Cvlan Range;
        data: min, mask: max, ext_data: (uint32*)vrange_gid. */
    case CTC_FIELD_KEY_CTAG_VALID:               /**< [D2] C-Vlan Exist. */
    case CTC_FIELD_KEY_CTAG_CFI:                 /**< [D2] Ctag Cfi. */
        if ( support_vsi_check && (mac_l3_key || mac_ipv6_key) &&
            key_field->type != CTC_FIELD_KEY_CTAG_VALID && key_field->type != CTC_FIELD_KEY_CTAG_CFI)
        {
            uint8 step = FlowTcamLookupCtl_gIngrAcl_1_aclL2L3KeySupportVsi_f - FlowTcamLookupCtl_gIngrAcl_0_aclL2L3KeySupportVsi_f;
            if (1 == GetFlowTcamLookupCtl(V, gIngrAcl_0_aclL2L3KeySupportVsi_f + step * pe->group->group_info.block_id , ds))
            {
                return CTC_E_NOT_SUPPORT;
            }
        }
        if (copp_key && !copp_key_use_ctag)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp_key copp_key_use_ctag:%d \n", copp_key_use_ctag);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && !fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d \n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_key && (pe->mac_key_vlan_mode == 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac key vlan_mode:%d \n", pe->mac_key_vlan_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (short_key && short_key_use_svlan)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "interface key use_svlan:%d \n", short_key_use_svlan);
            return CTC_E_INVALID_PARAM;
        }
        if(fwd_key && !GetFlowTcamLookupCtl(V,aclForwardingBasicKeyUseCvlan_f,ds))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "forward key in use svlan mode\n");
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key
            && pe->macl3basic_key_cvlan_mode == 2)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_basic_key cvlan_mode:%d \n", pe->macl3basic_key_cvlan_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_CVLAN_ID)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_CTAG_COS)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 7);
        }
        if (key_field->type == CTC_FIELD_KEY_CTAG_CFI)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;
    case CTC_FIELD_KEY_ETHER_TYPE:
        if ((fwd_key || fwd_ext_key || l3_key || l3_ext_key || mac_l3_key || mac_l3_ext_key) &&\
            (CTC_PARSER_L3_TYPE_NONE != l3_type || 0x0806 == key_field->data || 0x8035 == key_field->data))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The Key's l3 type must be none l3_type:%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if(set_l3_mask && (fwd_key || fwd_ext_key || l3_key || l3_ext_key || mac_l3_key || mac_l3_ext_key ))
        {
            ctc_field_key_t key_field_temp = {0};
            key_field_temp.type = CTC_FIELD_KEY_L3_TYPE;
            key_field_temp.data = CTC_PARSER_L3_TYPE_NONE;
            key_field_temp.mask = 0xF;
            if(p_usw_acl_master[lchip]->build_key_func[pe->key_type])
            {
                CTC_ERROR_RETURN(p_usw_acl_master[lchip]->build_key_func[pe->key_type](lchip, &key_field_temp, pe, is_add));
            }
        }
        break;
    case CTC_FIELD_KEY_L2_TYPE:
        if (l2type_use_vlanNum )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The Key l2type_use_vlanNum:%d \n", l2type_use_vlanNum);
            return CTC_E_INVALID_PARAM;

        }
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        break;
    case CTC_FIELD_KEY_VLAN_NUM:
        if (!l2type_use_vlanNum )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The Key l2type_use_vlanNum:%d \n", l2type_use_vlanNum);
            return CTC_E_INVALID_PARAM;

        }
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        break;
    case CTC_FIELD_KEY_L3_TYPE:                  /**< [D2] Layer 3 type (ctc_parser_l3_type_t). */
        if (copp_key && !copp_key_use_l3l4_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp_key  use_l3l4_type:%d \n", copp_key_use_l3l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if(copp_basic_key && copp_key_use_udf)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp basic key now use udf\n");
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_L4_TYPE:                  /**< [D2] Layer 4 type (ctc_parser_l4_type_t). */
        if (copp_key && !copp_key_use_l3l4_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp_key  use_l3l4_type:%d \n", copp_key_use_l3l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && (l3_type != CTC_PARSER_L3_TYPE_IPV4))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key l3_type must be ipv4, Current L3 Type:%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (CTC_PARSER_L3_TYPE_NONE == l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Current L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_L4_USER_TYPE:             /**< [D2] Layer 4 Usertype (ctc_parser_l4_usertype_t). */
        if (CTC_PARSER_L4_TYPE_NONE == l4_type || (pe->key_l4_port_mode == 1 && key_field->data == CTC_PARSER_L4_USER_TYPE_UDP_VXLAN))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Current L4 Type :%d \n", l4_type);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_IP_SA:                    /**< [D2] Source IPv4 Address. */
		if (l3_type != CTC_PARSER_L3_TYPE_IPV4)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv4, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
		if (copp_basic_key && (!copp_basic_key_ipaddr_use_ipsa) )
        {
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IP_DA:                    /**< [D2] Destination IPv4 Address. */
        if (l3_type != CTC_PARSER_L3_TYPE_IPV4)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv4, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
		if (copp_basic_key && copp_basic_key_ipaddr_use_ipsa)
        {
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IPV6_SA:                  /**< [D2] Source IPv6 Address. */
        if (l3_type != CTC_PARSER_L3_TYPE_IPV6)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
		if(copp_basic_key)
		{
			SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp basic key no support ipv6 address\n");
            return CTC_E_INVALID_PARAM;
		}
        if (cid_key && cid_key_v6_use_ipda)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "cid_key , use_ipda :%d \n", cid_key_v6_use_ipda);
            return CTC_E_INVALID_PARAM;
        }
        if (copp_ext_key && !copp_ext_key_ipv6sa  && copp_ext_key_use_udf)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp ext key , ipsa and udf share, now only use udf\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IPV6_DA:                  /**< [D2] Destination IPv6 Address. */
        if (l3_type != CTC_PARSER_L3_TYPE_IPV6)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (cid_key && !cid_key_v6_use_ipda)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "cid_key , use_ipda :%d \n", cid_key_v6_use_ipda);
            return CTC_E_INVALID_PARAM;
        }
		if(copp_basic_key)
		{
			SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp basic key no support ipv6 address\n");
            return CTC_E_INVALID_PARAM;
		}
        if (copp_ext_key && (copp_ext_key_ipv6sa && copp_ext_key_use_udf))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp ext key , ipda and udf share same field,now only use udf\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IPV6_FLOW_LABEL:          /**< [D2] Ipv6 Flow label*/
        if (l3_type != CTC_PARSER_L3_TYPE_IPV6)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFF);
        break;
    case CTC_FIELD_KEY_IP_TTL:
        if (l3_key && DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "TMM egress l3 key not support! \n");
            return CTC_E_INVALID_PARAM;
        }
        if (l3_type != CTC_PARSER_L3_TYPE_IPV4
            && l3_type != CTC_PARSER_L3_TYPE_IPV6)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6 or ipv4, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (l3_key && (l3_key_share_field_mode != 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode :%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;
    case CTC_FIELD_KEY_IP_DSCP:                  /**< [D2] DSCP. */
        if (!DRV_FROM_TMM(lchip) && l3_key && ((l3_key_share_field_mode == 0 &&\
            GetFlowTcamLookupCtl(V,l3Key160FullRangeBitMapMode_f, ds)) || l3_key_share_field_mode == 3  ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode :%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (l3_type != CTC_PARSER_L3_TYPE_IPV4
            && l3_type != CTC_PARSER_L3_TYPE_IPV6)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6 or ipv4, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        break;
    case CTC_FIELD_KEY_IP_PKT_LEN_RANGE:
    case CTC_FIELD_KEY_L4_DST_PORT_RANGE:
    case CTC_FIELD_KEY_L4_SRC_PORT_RANGE:
        if (l3_key && DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "TMM egress l3 key not support! \n");
            return CTC_E_INVALID_PARAM;
        }
        if (l3_key && (l3_key_share_field_mode != 0   ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode :%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (l3_type != CTC_PARSER_L3_TYPE_IPV4
            && l3_type != CTC_PARSER_L3_TYPE_IPV6)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6 or ipv4, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IP_PROTOCOL:              /**< [D2] Ip Protocol. */
    case CTC_FIELD_KEY_IP_PRECEDENCE:            /**< [D2] Precedence. */
    case CTC_FIELD_KEY_IP_ECN:                   /**< [D2] Ecn. */
    case CTC_FIELD_KEY_IP_FRAG:                  /**< [D2] IP Fragment Information. */
    case CTC_FIELD_KEY_IP_HDR_ERROR:             /**< [D2] Ip Header Error. */
    case CTC_FIELD_KEY_IP_OPTIONS:               /**< [D2] Ip Options. */
        if (CTC_FIELD_KEY_IP_FRAG == key_field->type && \
            ((DRV_IS_TSINGMA(lchip) && (copp_basic_key || udf_key)) || (DRV_FROM_TMM(lchip)&&(l3_key ||ipv6_key))) && \
            !(CTC_IP_FRAG_NON == key_field->data || CTC_IP_FRAG_YES == key_field->data))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Ip frag only support none and yes\n");
            return CTC_E_NOT_SUPPORT;
        }
        if ((key_field->type == CTC_FIELD_KEY_IP_HDR_ERROR) && DRV_FROM_TMM(lchip) && (pe->group->group_info.dir == CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Ip hdr error not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if (l3_type != CTC_PARSER_L3_TYPE_IPV4
            && l3_type != CTC_PARSER_L3_TYPE_IPV6 && l3_type != CTC_PARSER_L3_TYPE_IP)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6 or ipv4, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_IP_PROTOCOL)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (key_field->type == CTC_FIELD_KEY_IP_PRECEDENCE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x7);
        }
        if (key_field->type == CTC_FIELD_KEY_IP_ECN)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 3);
        }
        if (key_field->type == CTC_FIELD_KEY_IP_FRAG)
        {
            /*key judge*/
        }
        if (key_field->type == CTC_FIELD_KEY_IP_HDR_ERROR
            || key_field->type == CTC_FIELD_KEY_IP_OPTIONS)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;
    case CTC_FIELD_KEY_L4_DST_PORT:
    case CTC_FIELD_KEY_L4_SRC_PORT:
        if (CTC_PARSER_L3_TYPE_IPV4 != l3_type
            && CTC_PARSER_L3_TYPE_IPV6 != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 Type is not Ipv6 or ipv4, L3 Type :%d \n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (l4_type == CTC_PARSER_L4_TYPE_NONE
            || CTC_PARSER_L4_TYPE_ICMP == l4_type
        || CTC_PARSER_L4_TYPE_IGMP == l4_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L4 port's L4 Type is conflict, L4 Type :%d \n", l4_type);
            return CTC_E_PARAM_CONFLICT;
        }
        if (pe->key_l4_port_mode != 1 && pe->key_l4_port_mode != 0 && !DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L4 port's share is conflit, l4_port_mode:%d \n", pe->key_l4_port_mode);
            return CTC_E_PARAM_CONFLICT;
        }

        if (key_field->type == CTC_FIELD_KEY_L4_DST_PORT
            || key_field->type == CTC_FIELD_KEY_L4_SRC_PORT)
        {
            if(CTC_PARSER_L4_USER_TYPE_UDP_VXLAN == l4_user_type || CTC_PARSER_L4_TYPE_GRE == l4_type)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L4 type is conflit, l4_type:%d, l4_user_type:%d.\n", l4_type, l4_user_type);
                return CTC_E_INVALID_PARAM;
            }
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        }
        break;
    case CTC_FIELD_KEY_TCP_ECN:                  /**< [D2] TCP Ecn. */
    case CTC_FIELD_KEY_TCP_FLAGS:                /**< [D2] TCP Flags (ctc_acl_tcp_flag_flag_t). */
        if (DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS) && (glb_acl_prop.key_stk_hdr_en!=0))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key stk hdr enable! \n");
            return CTC_E_INVALID_PARAM;
        }
        if ((l3_type != CTC_PARSER_L3_TYPE_IPV4  && l3_type != CTC_PARSER_L3_TYPE_IPV6)
            || (l4_type != CTC_PARSER_L4_TYPE_TCP))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "TCP param is mismatch , l3_type :%d l4_type:%d \n", l3_type, l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if (!DRV_FROM_TMM(lchip) && l3_key && (l3_key_share_field_mode != 2   ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode:%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_TCP_ECN)
        {
            if (l3_key || cid_key)
            {
                CTC_MAX_VALUE_CHECK(key_field->data, 0x3);/* 2bit */
            }
            else
            {
                CTC_MAX_VALUE_CHECK(key_field->data, 0x7);/* 3bit */
            }
        }
        if (key_field->type == CTC_FIELD_KEY_TCP_FLAGS)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        }
        if (pe->key_l4_port_mode != 1 && pe->key_l4_port_mode != 0 )
        {
            return CTC_E_PARAM_CONFLICT;
        }
        break;
    case CTC_FIELD_KEY_ICMP_CODE:
    case CTC_FIELD_KEY_ICMP_TYPE:
        if ((l3_type != CTC_PARSER_L3_TYPE_IPV4 && l3_type != CTC_PARSER_L3_TYPE_IPV6)
            || (l4_type != CTC_PARSER_L4_TYPE_ICMP))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Param is mismatch , l3_type :%d l4_type:%d \n", l3_type, l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_ICMP_CODE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (key_field->type == CTC_FIELD_KEY_ICMP_TYPE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (pe->key_l4_port_mode != 1 && pe->key_l4_port_mode != 0 && !DRV_FROM_TMM(lchip))
        {
            return CTC_E_PARAM_CONFLICT;
        }
        break;
    case CTC_FIELD_KEY_IGMP_TYPE:
        if ((l3_type != CTC_PARSER_L3_TYPE_IPV4 && l3_type != CTC_PARSER_L3_TYPE_IPV6)
            || (l4_type != CTC_PARSER_L4_TYPE_IGMP))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Param is mismatch , l3_type :%d l4_type:%d \n", l3_type, l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if (pe->key_l4_port_mode != 1 && pe->key_l4_port_mode != 0 && !DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "share filed key_l4_port_mode:%d \n", pe->key_l4_port_mode);
            return CTC_E_PARAM_CONFLICT;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        break;

    case CTC_FIELD_KEY_VXLAN_FLAGS:
    case CTC_FIELD_KEY_VXLAN_RSV1:
    case CTC_FIELD_KEY_VXLAN_RSV2:
        if ((l3_type != CTC_PARSER_L3_TYPE_IPV4 && l3_type != CTC_PARSER_L3_TYPE_IPV6)
            || (l4_type != CTC_PARSER_L4_TYPE_UDP)
            || (l4_user_type != CTC_PARSER_L4_USER_TYPE_UDP_VXLAN))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Param is mismatch , l3_type :%d l4_type:%d \n", l3_type, l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if ((CTC_FIELD_KEY_VXLAN_FLAGS != key_field->type) && (fwd_key || fwd_ext_key) && (l3_type != CTC_PARSER_L3_TYPE_IPV4))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd and fwd ext key support the field only for ipv4 packet \n");
            return CTC_E_NOT_SUPPORT;
        }
        if ((CTC_FIELD_KEY_VXLAN_FLAGS != key_field->type) && (ipv6_ext_key || CTC_ACL_KEY_MAC_IPV6 == pe->key_type) && (pe->key_mergedata_mode == 2))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Merge Key check conflict,key_mergedata_mode:%d \n", pe->key_mergedata_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (CTC_FIELD_KEY_VXLAN_RSV1 == key_field->type)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        break;

    case CTC_FIELD_KEY_VN_ID:
        if ((l3_type != CTC_PARSER_L3_TYPE_IPV4 && l3_type != CTC_PARSER_L3_TYPE_IPV6)
            || (l4_type != CTC_PARSER_L4_TYPE_UDP)
        || (l4_user_type != CTC_PARSER_L4_USER_TYPE_UDP_VXLAN))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Param is mismatch , l3_type :%d l4_type:%d \n", l3_type, l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if (copp_ext_key)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp ext key not support the field\n");
            return CTC_E_INVALID_PARAM;
        }
        if (pe->key_l4_port_mode != 2 && pe->key_l4_port_mode != 0 )
        {
            return CTC_E_PARAM_CONFLICT;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_GRE_KEY:                     /**< [D2] Gre Key. */
        if (copp_ext_key)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp ext key not support the field\n");
            return CTC_E_INVALID_PARAM;
        }
        if ((l3_type != CTC_PARSER_L3_TYPE_IPV4 && l3_type != CTC_PARSER_L3_TYPE_IPV6)
            || (l4_type != CTC_PARSER_L4_TYPE_GRE))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "param is mismatch , l3_type :%d l4_type:%d \n", l3_type, l4_type);
            return CTC_E_INVALID_PARAM;
        }

        if (pe->key_l4_port_mode != 3 && pe->key_l4_port_mode != 0 )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "share filed key_l4_port_mode:%d \n", pe->key_l4_port_mode);
            return CTC_E_PARAM_CONFLICT;
        }
        break;
    case CTC_FIELD_KEY_NVGRE_KEY:                  /**< [D2] NVGre Key. */
        if (copp_ext_key)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp ext key not support the field\n");
            return CTC_E_INVALID_PARAM;
        }
        if ((l3_type != CTC_PARSER_L3_TYPE_IPV4 && l3_type != CTC_PARSER_L3_TYPE_IPV6)
            || (l4_type != CTC_PARSER_L4_TYPE_GRE))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "param is mismatch , l3_type :%d l4_type:%d \n", l3_type, l4_type);
            return CTC_E_INVALID_PARAM;
        }
        if (pe->key_l4_port_mode != 3 && pe->key_l4_port_mode != 0 )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "share filed key_l4_port_mode:%d \n", pe->key_l4_port_mode);
            return CTC_E_PARAM_CONFLICT;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_ARP_OP_CODE:
    case CTC_FIELD_KEY_ARP_PROTOCOL_TYPE:
    case CTC_FIELD_KEY_ARP_SENDER_IP:
    case CTC_FIELD_KEY_ARP_TARGET_IP:
    case CTC_FIELD_KEY_ARP_MAC_DA_CHK_FAIL:
    case CTC_FIELD_KEY_ARP_MAC_SA_CHK_FAIL:
    case CTC_FIELD_KEY_ARP_SENDERIP_CHK_FAIL:
    case CTC_FIELD_KEY_ARP_TARGETIP_CHK_FAIL:
    case  CTC_FIELD_KEY_SENDER_MAC:                   /**< [D2] Ethernet Address of sender of ARP Header */
    case  CTC_FIELD_KEY_TARGET_MAC:                   /**< [D2] Ethernet Address of destination of ARP Header */
    case CTC_FIELD_KEY_GARP:
    case CTC_FIELD_KEY_RARP:
        if (CTC_FIELD_KEY_RARP == key_field->type && DRV_IS_DUET2(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "RARP is not support\n");
            return CTC_E_NOT_SUPPORT;
        }
        if (CTC_PARSER_L3_TYPE_ARP != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not ARP l3 type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_ext_key
            && (key_field->type == CTC_FIELD_KEY_SENDER_MAC)
        && !mac_l3_ext_key_mac_sa_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_ext_key mac_sa_mode:%d \n", mac_l3_ext_key_mac_sa_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_ext_key
            && (key_field->type == CTC_FIELD_KEY_TARGET_MAC )
        && !mac_l3_ext_key_mac_da_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_ext_key mac_da_mode:%d \n", mac_l3_ext_key_mac_da_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key
            && (key_field->type == CTC_FIELD_KEY_SENDER_MAC)
        && !mac_l3_key_mac_sa_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_key mac_sa_mode:%d \n", mac_l3_key_mac_sa_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key
            && (key_field->type == CTC_FIELD_KEY_TARGET_MAC)
        && !mac_l3_key_mac_da_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_key mac_da_mode:%d \n", mac_l3_key_mac_da_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (((mac_l3_key && DRV_IS_DUET2(lchip)) || copp_basic_key)
            && key_field->type == CTC_FIELD_KEY_TARGET_MAC )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key not support the field\n");
            return CTC_E_INVALID_PARAM;
        }
        if (copp_basic_key
            && key_field->type == CTC_FIELD_KEY_SENDER_MAC
        && !copp_key_basic_mac_da_mode)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp_key mac_da_mode:%d \n", copp_key_basic_mac_da_mode);
            return CTC_E_INVALID_PARAM;
        }


        if (key_field->type == CTC_FIELD_KEY_ARP_OP_CODE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        }
        if (key_field->type== CTC_FIELD_KEY_ARP_PROTOCOL_TYPE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_ARP_MAC_DA_CHK_FAIL
            || key_field->type == CTC_FIELD_KEY_ARP_MAC_SA_CHK_FAIL
        || key_field->type == CTC_FIELD_KEY_ARP_SENDERIP_CHK_FAIL
        || key_field->type == CTC_FIELD_KEY_ARP_TARGETIP_CHK_FAIL
        || key_field->type == CTC_FIELD_KEY_GARP)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;
    case CTC_FIELD_KEY_LABEL_NUM:                /**< [D2] MPLS Label Number. */
    case  CTC_FIELD_KEY_MPLS_LABEL0:              /**< [D2] Label Field of the MPLS Label 0. */
    case  CTC_FIELD_KEY_MPLS_EXP0:                /**< [D2] Exp Field of the MPLS Label 0.*/
    case  CTC_FIELD_KEY_MPLS_SBIT0:               /**< [D2] S-bit Field of the MPLS Label 0.*/
    case  CTC_FIELD_KEY_MPLS_TTL0:                /**< [D2] Ttl Field of the MPLS Label 0.*/
    case  CTC_FIELD_KEY_MPLS_LABEL1:              /**< [D2] Label Field of the MPLS Label 1. */
    case  CTC_FIELD_KEY_MPLS_EXP1:                /**< [D2] Exp Field of the MPLS Label 1.*/
    case  CTC_FIELD_KEY_MPLS_SBIT1:               /**< [D2] S-bit Field of the MPLS Label 1.*/
    case  CTC_FIELD_KEY_MPLS_TTL1:                /**< [D2] Ttl Field of the MPLS Label 1.*/
    case  CTC_FIELD_KEY_MPLS_LABEL2:              /**< [D2] Label Field of the MPLS Label 2. */
    case CTC_FIELD_KEY_MPLS_EXP2:                /**< [D2] Exp Field of the MPLS Label 2.*/
    case CTC_FIELD_KEY_MPLS_SBIT2:               /**< [D2] S-bit Field of the MPLS Label 2.*/
    case CTC_FIELD_KEY_MPLS_TTL2:                /**< [D2] Ttl Field of the MPLS Label 2.*/
        if (CTC_PARSER_L3_TYPE_MPLS != l3_type && CTC_PARSER_L3_TYPE_MPLS_MCAST!=l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not MPLS l3 type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_LABEL_NUM)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, MCHIP_CAP(SYS_CAP_ACL_LABEL_NUM));
        }
        if (key_field->type == CTC_FIELD_KEY_MPLS_LABEL0
            || key_field->type == CTC_FIELD_KEY_MPLS_LABEL1
        || key_field->type == CTC_FIELD_KEY_MPLS_LABEL2)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_MPLS_EXP0
            || key_field->type == CTC_FIELD_KEY_MPLS_EXP1
        || key_field->type == CTC_FIELD_KEY_MPLS_EXP2)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 7);
        }
        if (key_field->type == CTC_FIELD_KEY_MPLS_TTL0
            || key_field->type == CTC_FIELD_KEY_MPLS_TTL1
        || key_field->type == CTC_FIELD_KEY_MPLS_TTL2)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (key_field->type == CTC_FIELD_KEY_MPLS_SBIT0
            || key_field->type == CTC_FIELD_KEY_MPLS_SBIT1
        || key_field->type == CTC_FIELD_KEY_MPLS_SBIT2)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;
    case CTC_FIELD_KEY_INTERFACE_ID:
        if (!DRV_FROM_TMM(lchip) && l3_key && (CTC_PARSER_L3_TYPE_MPLS != l3_type) && (CTC_PARSER_L3_TYPE_MPLS_MCAST!=l3_type))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "when l3_key use interface id ,the pkt must be mpls :%d\n", pe->l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (!DRV_FROM_TMM(lchip) && (l3_ext_key || mac_l3_key)&& (CTC_PARSER_L3_TYPE_MPLS != l3_type) && (CTC_PARSER_L3_TYPE_MPLS_MCAST!=l3_type) && !CTC_FLAG_ISSET(pe->flag, SYS_ACL_ENTRY_FLAG_Y1731))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "when l3_key or mac_l3_key use interface id ,the pkt must be mpls or ether_oam:%d\n", pe->l3_type);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, (MCHIP_CAP(SYS_CAP_SPEC_L3IF_NUM)-1));/*10bit; 1023 is reserved*/
        break;
    case CTC_FIELD_KEY_NSH_CBIT:                 /**< [D2] C-bit of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_OBIT:                 /**< [D2] O-bit of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_NEXT_PROTOCOL:        /**< [D2] Next Protocol of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_SI:                  /**< [D2] Service Index of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_SPI:                  /**< [D2] Service Path ID of the Network Service Header. */
        if (!DRV_IS_DUET2(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "nsh not support\n");
            return CTC_E_NOT_SUPPORT;
        }
        /*forwarding ext key:nsh and udf is union*/
        if (fwd_ext_key && fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr :%d\n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && !fwd_ext_key_udf_use_nsh)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key udf_use_nsh :%d\n", fwd_ext_key_udf_use_nsh);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && fwd_ext_key_udf_use_nsh
            && (pe->fwd_key_nsh_mode == 2))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key udf_use_nsh :%d,fwd_key_nsh_mode:%d\n", fwd_ext_key_udf_use_nsh, pe->fwd_key_nsh_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_NSH_CBIT
            || key_field->type == CTC_FIELD_KEY_NSH_OBIT)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x1);
        }
        if (key_field->type == CTC_FIELD_KEY_NSH_NEXT_PROTOCOL)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (key_field->type == CTC_FIELD_KEY_NSH_SI)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (key_field->type == CTC_FIELD_KEY_NSH_SPI)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        }
        break;
        /*Ether OAM packet field*/
    case CTC_FIELD_KEY_IS_Y1731_OAM:             /**< [D2] Is Y1731 Oam. */
        if (DRV_FROM_TMM(lchip) && (pe->group->group_info.dir == CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Y1731 oam not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if(CTC_PARSER_L4_USER_TYPE_ACHOAM_ACHY1731 != l4_user_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Y1731 l4 user type must be ach oam\n");
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0x1);
        break;
    case CTC_FIELD_KEY_ETHER_OAM_LEVEL:          /**< [D2] Oam Level. */
    case CTC_FIELD_KEY_ETHER_OAM_OP_CODE:        /**< [D2] Oam Opcode. */
    case CTC_FIELD_KEY_ETHER_OAM_VERSION:        /**< [D2] Oam Version. */
        if (DRV_FROM_TMM(lchip) && (CTC_PARSER_L3_TYPE_ETHER_OAM != l3_type) && (pe->group->group_info.dir == CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Y1731 oam not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if (!(CTC_PARSER_L3_TYPE_ETHER_OAM == l3_type
            || CTC_FLAG_ISSET(pe->flag, SYS_ACL_ENTRY_FLAG_Y1731)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Param is mismatch: l3_type:%d l4_type:%d,l4_user_type:%d\n", l3_type, l4_type, l4_user_type);
            return CTC_E_INVALID_PARAM;
        }

        if (key_field->type == CTC_FIELD_KEY_ETHER_OAM_LEVEL)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 7);
        }
        if (key_field->type == CTC_FIELD_KEY_ETHER_OAM_OP_CODE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (key_field->type == CTC_FIELD_KEY_ETHER_OAM_VERSION)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x1F);
        }
        break;
        /*Slow Protocol packet field*/
    case CTC_FIELD_KEY_SLOW_PROTOCOL_CODE:       /**< [D2] Slow Protocol Code. */
    case CTC_FIELD_KEY_SLOW_PROTOCOL_FLAGS:      /**< [D2] Slow Protocol Flags. */
    case CTC_FIELD_KEY_SLOW_PROTOCOL_SUB_TYPE:   /**< [D2] Slow Protocol Sub Type. */
        if (CTC_PARSER_L3_TYPE_SLOW_PROTO != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not slow protocol l3_type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_SLOW_PROTOCOL_CODE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        if (key_field->type == CTC_FIELD_KEY_SLOW_PROTOCOL_FLAGS)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_SLOW_PROTOCOL_SUB_TYPE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFF);
        }
        break;
    case CTC_FIELD_KEY_PTP_MESSAGE_TYPE:       /**< [D2] Slow Protocol Code. */
    case CTC_FIELD_KEY_PTP_VERSION:      /**< [D2] Slow Protocol Flags. */
        if (CTC_PARSER_L3_TYPE_PTP != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not PTP  l3_type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_PTP_MESSAGE_TYPE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        }
        if (key_field->type == CTC_FIELD_KEY_PTP_VERSION)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 3);
        }
        break;
    case CTC_FIELD_KEY_FCOE_DST_FCID:       /**< [D2] Slow Protocol Code. */
    case CTC_FIELD_KEY_FCOE_SRC_FCID:      /**< [D2] Slow Protocol Flags. */
        if (CTC_PARSER_L3_TYPE_FCOE != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not FCOE l3_type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        break;
    case CTC_FIELD_KEY_INGRESS_NICKNAME:         /**< [D2] Ingress Nick Name. */
    case CTC_FIELD_KEY_EGRESS_NICKNAME:          /**< [D2] Egress Nick Name. */
    case CTC_FIELD_KEY_IS_ESADI:                 /**< [D2] Is Esadi. */
    case CTC_FIELD_KEY_IS_TRILL_CHANNEL:         /**< [D2] Is Trill Channel. */
    case CTC_FIELD_KEY_TRILL_INNER_VLANID:       /**< [D2] Trill Inner Vlan Id. */
    case CTC_FIELD_KEY_TRILL_INNER_VLANID_VALID: /**< [D2] Trill Inner Vlan Id Valid. */

    case CTC_FIELD_KEY_TRILL_LENGTH:             /**< [D2] Trill Length. */
    case CTC_FIELD_KEY_TRILL_MULTIHOP:           /**< [D2] Trill Multi-Hop. */
    case CTC_FIELD_KEY_TRILL_MULTICAST:          /**< [D2] Trill MultiCast. */
    case CTC_FIELD_KEY_TRILL_VERSION:            /**< [D2] Trill Version. */
    case CTC_FIELD_KEY_TRILL_TTL:                /**< [D2] Trill Ttl. */
        if (CTC_PARSER_L3_TYPE_TRILL != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not TRILL l3_type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_IS_ESADI
            || key_field->type == CTC_FIELD_KEY_IS_TRILL_CHANNEL
        || key_field->type == CTC_FIELD_KEY_TRILL_MULTIHOP
        || key_field->type == CTC_FIELD_KEY_TRILL_MULTICAST
        || key_field->type == CTC_FIELD_KEY_TRILL_INNER_VLANID_VALID)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        if (key_field->type == CTC_FIELD_KEY_INGRESS_NICKNAME
            || key_field->type == CTC_FIELD_KEY_EGRESS_NICKNAME )
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_TRILL_INNER_VLANID)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_TRILL_LENGTH)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x3FFF);
        }
        if (key_field->type == CTC_FIELD_KEY_TRILL_TTL)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        }
        if (key_field->type== CTC_FIELD_KEY_TRILL_VERSION)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 3);
        }
        break;
    case CTC_FIELD_KEY_DOT1AE_UNKNOW_PKT:        /**< [D2] Unknow 802.1AE packet, SecTag error or Mode not support. */
    case CTC_FIELD_KEY_DOT1AE_ES:                /**< [D2] End Station (ES) bit. */
    case CTC_FIELD_KEY_DOT1AE_SC:                /**< [D2] Secure Channel (SC) bit. */
    case CTC_FIELD_KEY_DOT1AE_AN:                /**< [D2] Association Number (AN). */
    case CTC_FIELD_KEY_DOT1AE_SL:                /**< [D2] Short Length (SL). */
    case CTC_FIELD_KEY_DOT1AE_PN:                /**< [D2] Packet Number. */
    case CTC_FIELD_KEY_DOT1AE_SCI:               /**< [D2] Secure Channel Identifier. */
    case CTC_FIELD_KEY_DOT1AE_CBIT :            /**< [TM] Changed Text. */
    case CTC_FIELD_KEY_DOT1AE_EBIT :            /**< [TM] Encryption. */
    case CTC_FIELD_KEY_DOT1AE_SCB :             /**< [TM] Single Copy Broadcast. */
    case CTC_FIELD_KEY_DOT1AE_VER :             /**< [TM] Version number. */
        if (DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Dot1ae not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if (CTC_PARSER_L3_TYPE_DOT1AE != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not DOT1AE l3_type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_DOT1AE_ES \
        || key_field->type == CTC_FIELD_KEY_DOT1AE_SC \
        || key_field->type == CTC_FIELD_KEY_DOT1AE_UNKNOW_PKT \
        || key_field->type == CTC_FIELD_KEY_DOT1AE_CBIT \
        || key_field->type == CTC_FIELD_KEY_DOT1AE_EBIT \
        || key_field->type == CTC_FIELD_KEY_DOT1AE_SCB \
        || key_field->type == CTC_FIELD_KEY_DOT1AE_VER)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        if (key_field->type == CTC_FIELD_KEY_DOT1AE_AN)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 3);
        }
        if (key_field->type == CTC_FIELD_KEY_DOT1AE_SL)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x3F);
        }
        if (key_field->type == CTC_FIELD_KEY_DOT1AE_SCI)
        {
            /*64 bit*/
        }
        break;
        /*SATPDU packet field*/
    case  CTC_FIELD_KEY_SATPDU_MEF_OUI:           /**< [D2] Satpdu Metro Ethernet Forum Oui.*/
    case CTC_FIELD_KEY_SATPDU_OUI_SUB_TYPE:      /**< [D2] Satpdu Oui Sub type.*/
    case  CTC_FIELD_KEY_SATPDU_PDU_BYTE:          /**< [D2] Satpdu Byte.*/
        if (CTC_PARSER_L3_TYPE_SATPDU != l3_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "L3 type is not SATPDU l3_type:%d\n", l3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_SATPDU_MEF_OUI)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_SATPDU_OUI_SUB_TYPE)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        }
        if (key_field->type == CTC_FIELD_KEY_SATPDU_PDU_BYTE)
        {
            /*64 bit*/
        }
        break;
        /*Wlan packet field*/
    case CTC_FIELD_KEY_WLAN_RADIO_MAC:         /**< [D2] Wlan Radio Mac.*/
    case CTC_FIELD_KEY_WLAN_RADIO_ID:          /**< [D2] Wlan Radio Id.*/
    case  CTC_FIELD_KEY_WLAN_CTL_PKT:           /**< [D2] Wlan Control Packet.*/
        if (DRV_FROM_TMM(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "WLAN not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if (CTC_PARSER_L4_TYPE_UDP != l4_type
            && CTC_PARSER_L4_USER_TYPE_UDP_CAPWAP != l4_user_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "WLAN param is mismatch l3_type:%d l4_user_type:%d\n", l4_type, l4_user_type);
            return CTC_E_INVALID_PARAM;
        }
        if (pe->key_mergedata_mode == 2)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Merge Key check conflict,key_mergedata_mode:%d \n", pe->key_mergedata_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (key_field->type == CTC_FIELD_KEY_WLAN_RADIO_ID)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0x1F);
        }
        if (key_field->type == CTC_FIELD_KEY_WLAN_CTL_PKT)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;
    case CTC_FIELD_KEY_UDF:
    case CTC_FIELD_KEY_UDF_AD_ID:
        if (DRV_FROM_TMM(lchip) && (pe->group->group_info.dir == CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "UDF not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if (!fwd_ext_key && !udf_key && !ipv6_ext_key && !mac_l3_ext_key && !copp_ext_key && !copp_key)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "UDF must use fwd_ext_key ipv6_ext_key or udf_key or mac l3 ext key or copp ext key\n");
            return CTC_E_INVALID_PARAM;
        }

        if (fwd_ext_key && fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d\n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }

        if (fwd_ext_key && fwd_ext_key_udf_use_nsh
            && (pe->fwd_key_nsh_mode == 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key udf_use_nsh:%d,fwd_key_nsh_mode:%d\n", fwd_ext_key_udf_use_nsh, pe->fwd_key_nsh_mode);
            return CTC_E_INVALID_PARAM;
        }
        if(copp_ext_key && !copp_ext_key_use_udf)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp_ext_key udf and ip v6 address is share & now only use ip v6 address\n");
            return CTC_E_INVALID_PARAM;
        }
        if(copp_basic_key && !copp_key_use_udf)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "copp basic key now use l3 info\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_AWARE_TUNNEL_INFO:
        if (DRV_FROM_TMM(lchip) && (pe->group->group_info.dir == CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Aware tunnel info not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if(fwd_ext_key && (l3_type != CTC_PARSER_L3_TYPE_IPV4))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Only ipv4 packet support aware tunnel info in fwd ext key\n");
            return CTC_E_INVALID_PARAM;
        }
        if (pe->key_mergedata_mode == 1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Merge Key check conflict,key_mergedata_mode:%d \n", pe->key_mergedata_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (CTC_PARSER_L4_TYPE_UDP == l4_type
            && CTC_PARSER_L4_USER_TYPE_UDP_VXLAN == l4_user_type)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed must be decapsulated packet, l4_type:%d,l4_user_type:%d\n", l4_type, l4_user_type);
            return CTC_E_INVALID_PARAM;
        }
        if (CTC_PARSER_L4_TYPE_UDP == l4_type
            && CTC_PARSER_L4_USER_TYPE_UDP_CAPWAP == l4_user_type )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed must be decapsulated packet, l4_type:%d,l4_user_type:%d\n", l4_type, l4_user_type);
            return CTC_E_INVALID_PARAM;
        }
        if (CTC_PARSER_L4_TYPE_GRE == l4_type )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed must be decapsulated packet, l4_type:%d,l4_user_type:%d\n", l4_type, l4_user_type);
            return CTC_E_INVALID_PARAM;
        }
        if (!arware_tunnel_info)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed must be decapsulated packet, arware_tunnel_info:%d\n", arware_tunnel_info);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key && (pe->macl3basic_key_cvlan_mode == 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_basic_key cvlan_mode:%d \n", pe->macl3basic_key_cvlan_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (mac_l3_key && (pe->macl3basic_key_macda_mode == 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_l3_basic_key mac_da_mode:%d \n", pe->macl3basic_key_macda_mode);
            return CTC_E_INVALID_PARAM;
        }
		if ( support_vsi_check && ((pe->key_type == CTC_ACL_KEY_MAC_IPV4) || (pe->key_type == CTC_ACL_KEY_MAC_IPV6)) )
        {
            uint8 step = FlowTcamLookupCtl_gIngrAcl_1_aclL2L3KeySupportVsi_f - FlowTcamLookupCtl_gIngrAcl_0_aclL2L3KeySupportVsi_f;
            if (1 == GetFlowTcamLookupCtl(V, gIngrAcl_0_aclL2L3KeySupportVsi_f + step * pe->group->group_info.block_id , ds))
            {
                return CTC_E_NOT_SUPPORT;
            }
        }
        break;
    case CTC_FIELD_KEY_VRFID:
        if (DRV_FROM_TMM(lchip) && (dir == CTC_EGRESS))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Vrfid not support \n");
            return CTC_E_NOT_SUPPORT;
        }
        if (l3_key && (l3_key_share_field_mode != 3  ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3_key share_field_mode:%d\n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
        SYS_IP_VRFID_CHECK(key_field->data);
        break;

    case CTC_FIELD_KEY_DECAP:                    /**< [D2] Decapsulation occurred. */
    case CTC_FIELD_KEY_ELEPHANT_PKT:             /**< [D2] Is Elephant. */
    case CTC_FIELD_KEY_VXLAN_PKT:                /**< [D2] Is Vxlan Packet. */
    case CTC_FIELD_KEY_ROUTED_PKT:               /**< [D2] Is Routed packet. */
    case CTC_FIELD_KEY_MACSA_HIT:                /**< [D2] Mac-Sa Lookup Hit. */
    case CTC_FIELD_KEY_MACDA_HIT:                /**< [D2] Mac-Da Lookup Hit. */
    case CTC_FIELD_KEY_IPSA_HIT:                 /**< [D2] L3-Sa Lookup Hit. */
    case CTC_FIELD_KEY_IPSA_LKUP:                /**< [D2] L3-Sa Lookup Enable. */
    case CTC_FIELD_KEY_IPDA_LKUP:                /**< [D2] L3-Da Lookup Enable. */
    case CTC_FIELD_KEY_IPDA_HIT:                 /**< [D2] L3-Da Lookup Hit. */
    case CTC_FIELD_KEY_MACSA_LKUP:               /**< [D2] Mac-Sa Lookup Enable. */
    case CTC_FIELD_KEY_MACDA_LKUP:               /**< [D2] Mac-Da Lookup Enable. */
    case CTC_FIELD_KEY_L2_STATION_MOVE:          /**< [D2] L2 Station Move. */
    case CTC_FIELD_KEY_MAC_SECURITY_DISCARD:     /**< [D2] Mac Security Discard. */
    case CTC_FIELD_KEY_DISCARD:                  /**< [D2] Packet Is Flagged to be Discarded. */
    case CTC_FIELD_KEY_MCAST_RPF_CHECK_FAIL:     /**< [D2] Mcast Rpf Check Fail. */
        if (CTC_FIELD_KEY_DECAP == key_field->type && !DRV_IS_DUET2(lchip) && CTC_INGRESS != pe->group->group_info.dir)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Egress not support decap \n");
            return CTC_E_NOT_SUPPORT;
        }
        if ((CTC_FIELD_KEY_ELEPHANT_PKT == key_field->type || CTC_FIELD_KEY_MCAST_RPF_CHECK_FAIL == key_field->type) &&
            DRV_FROM_TMM(lchip) &&
            CTC_INGRESS != pe->group->group_info.dir)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Egress not support elephant \n");
            return CTC_E_NOT_SUPPORT;
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 1);
        break;
    case CTC_FIELD_KEY_PKT_FWD_TYPE:             /**< [D2] Packet Forwarding Type. Refer to ctc_acl_pkt_fwd_type_t */
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_CPU_REASON_ID:            /**< [D2] CPU Reason Id. */
        if (NULL == key_field->ext_data)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, CTC_PKT_CPU_REASON_MAX_COUNT);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(key_field->data, SYS_USW_ACL_MATCH_GRP_MAX_COUNT);
        }
        break;
    case CTC_FIELD_KEY_DST_GPORT:                /**< [D2] Fwd Destination Port. */
        SYS_GLOBAL_PORT_CHECK(key_field->data);
        break;
    case CTC_FIELD_KEY_DST_NHID:                 /**< [D2] Nexthop Id. */
        if(support_vsi_check)
        {
            if ( (pe->key_type == CTC_ACL_KEY_COPP && 1 == GetFlowTcamLookupCtl(V, coppBasicKeySupportVsi_f, ds))
            || (pe->key_type == CTC_ACL_KEY_COPP_EXT && 1 == GetFlowTcamLookupCtl(V, coppExtKeySupportVsi_f, ds)) )
            {
                return CTC_E_NOT_SUPPORT;
            }
            if ((pe->key_type == CTC_ACL_KEY_FWD && 1 == GetFlowTcamLookupCtl(V, forwardingBasicKeySupportVsi_f, ds))
            || (pe->key_type == CTC_ACL_KEY_FWD_EXT && 1 == GetFlowTcamLookupCtl(V, forwardingExtKeySupportVsi_f, ds)))
            {
                return CTC_E_NOT_SUPPORT;
            }
        }
        if (key_field->ext_data && (0 == key_field->data) && (0 == key_field->mask))
        {
            uint32 dsnh_num = 0;
            sys_usw_ftm_query_table_entry_num(lchip, DsNextHop4W_t, &dsnh_num);
            CTC_MAX_VALUE_CHECK(*(uint32*)key_field->ext_data, dsnh_num-1);
        }
        break;
    case CTC_FIELD_KEY_STP_STATE:
        CTC_MAX_VALUE_CHECK(key_field->data, 3);
        key_field->mask = 0x3;
        if(2 == key_field->data)
        {
            key_field->data = 3;
        }
        else if(3 == key_field->data)
        {
            key_field->data = 1;
            key_field->mask = 0x1;
        }
        break;
    case CTC_FIELD_KEY_VLAN_XLATE_HIT:
        if (CTC_EGRESS != pe->group->group_info.dir || DRV_IS_DUET2(lchip))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Ingress not support vlan xlate \n");
            return CTC_E_NOT_SUPPORT;
        }
        break;

    default:
        break;
    }

    /*check ext_data valid*/
    switch(key_field->type)
    {
    case CTC_FIELD_KEY_MAC_SA:                  /* 48bit*/
    case CTC_FIELD_KEY_MAC_DA:
    case CTC_FIELD_KEY_SENDER_MAC:
    case CTC_FIELD_KEY_TARGET_MAC:
    case CTC_FIELD_KEY_WLAN_RADIO_MAC:
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
    break;
    case CTC_FIELD_KEY_SVLAN_RANGE:  /**< [D2] Svlan Range; data: min, mask: max, ext_data: (uint32*)vrange_gid. */
    case CTC_FIELD_KEY_CVLAN_RANGE:  /**< [D2] Cvlan Range; data: min, mask: max, ext_data: (uint32*)vrange_gid. */
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_MAX_VALUE_CHECK(key_field->data, key_field->mask);
            SYS_ACL_VLAN_ID_CHECK(key_field->mask);
        }
    break;
    case CTC_FIELD_KEY_IPV6_SA:                  /**< [D2] Source IPv6 Address. 128bit */
    case CTC_FIELD_KEY_IPV6_DA:                  /**< [D2] Destination IPv6 Address. 128bit */
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
    break;
    case CTC_FIELD_KEY_SATPDU_PDU_BYTE:    /*64 bit*/
    case CTC_FIELD_KEY_DOT1AE_SCI:         /*64 bit*/
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
    break;
    case CTC_FIELD_KEY_UDF:
    case CTC_FIELD_KEY_UDF_AD_ID:
        if(is_add)
        {
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
        }
    break;
    case CTC_FIELD_KEY_PORT:
        {
            if(is_add)
            {
                ctc_field_port_t* p_field_port = (ctc_field_port_t*)key_field->ext_data;
                CTC_PTR_VALID_CHECK(key_field->ext_data);
                if(copp_key && \
                    (CTC_FIELD_PORT_TYPE_NONE != p_field_port->type) && (CTC_FIELD_PORT_TYPE_PORT_BITMAP !=p_field_port->type))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The key port type must be none or bitmap, key_port_type:%d\n", p_field_port->type);
                    return CTC_E_NOT_SUPPORT;
                }
                if((cid_key) && \
                    (CTC_FIELD_PORT_TYPE_GPORT==p_field_port->type || CTC_FIELD_PORT_TYPE_LOGIC_PORT==p_field_port->type || CTC_FIELD_PORT_TYPE_PORT_BITMAP==p_field_port->type ))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The key port type must not be gport ,logical port por bitmap, key_port_type:%d\n", p_field_port->type);
                    return CTC_E_NOT_SUPPORT;
                }
                if (udf_key && CTC_FIELD_PORT_TYPE_GPORT == p_field_port->type)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The key port type must not be gport, key_port_type:%d\n", p_field_port->type);
                    return CTC_E_NOT_SUPPORT;
                }
                CTC_ERROR_RETURN(_sys_usw_acl_check_port_info(lchip, pe, key_field));
            }
        }
    break;
    case CTC_FIELD_KEY_AWARE_TUNNEL_INFO:
        if(is_add)
        {
            ctc_acl_tunnel_data_t* p_tunnel_data = (ctc_acl_tunnel_data_t*)key_field->ext_data;
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            CTC_PTR_VALID_CHECK(key_field->ext_mask);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->type, 0x03);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->vxlan_vni, 0xFFFFFF);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->radio_id, 0x1F);
            CTC_MAX_VALUE_CHECK(p_tunnel_data->wlan_ctl_pkt, 0x01);
        }
    break;
    case CTC_FIELD_KEY_DISCARD:
        if(is_add && (key_field->ext_data) && (fwd_key || fwd_ext_key || copp_key))
        {
            discard_type = *((uint32*)(key_field->ext_data));
            CTC_ERROR_RETURN(_sys_usw_acl_check_discard_type(discard_type));
        }
        break;
    case CTC_FIELD_KEY_CLASS_ID:
        if(is_add)
        {
            SYS_USW_CLASS_ID_RANGE_CHECK(key_field->data);
        }
        break;
    }
    /*TMM check egress mac*/
    if (DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS) && mac_key)
    {
        switch(key_field->type)
        {
        case CTC_FIELD_KEY_MAC_SA:
            if (glb_acl_prop.key_stk_hdr_en!=0)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key stk hdr enable! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_ROUTED_PKT:
        case CTC_FIELD_KEY_DISCARD:
        case CTC_FIELD_KEY_FID:
        case CTC_FIELD_KEY_MIRROR_PKT:
        case CTC_FIELD_KEY_SRC_GPORT:
        case CTC_FIELD_KEY_STK_HDR_EXIST:
        case CTC_FIELD_KEY_PRIORITY:
            if (glb_acl_prop.key_stk_hdr_en==0)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key stk hdr disable! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        default :
            break;
        }
    }
    /*TMM check egress ipv4*/
    if (DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS) && l3_key)
    {
        switch(key_field->type)
        {
        case CTC_FIELD_KEY_DISCARD:
        case CTC_FIELD_KEY_MIRROR_PKT:
        case CTC_FIELD_KEY_STK_HDR_EXIST:
        case CTC_FIELD_KEY_PRIORITY:
            if (glb_acl_prop.key_stk_hdr_en==0)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "share fields can't be used as sh! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        default:
            break;
        }
    }
    if (DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS) && mac_l3_key)
    {
        switch(key_field->type)
        {
        case CTC_FIELD_KEY_DST_CID:
            if(2 != glb_acl_prop.l2l3_key_u2_mode)
            {
                if (pe->key_port_mode==1)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key_port_mode : %d! \n", pe->key_port_mode);
                    return CTC_E_NOT_SUPPORT;
                }
                if (!glb_acl_prop.key_cid_en || (glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_SRC))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "cid not support! \n");
                    return CTC_E_NOT_SUPPORT;
                }
            }
            break;
        case CTC_FIELD_KEY_METADATA:
            if (!(3 == glb_acl_prop.l2l3_key_u2_mode || 3 == glb_acl_prop.l2l3_key_u3_mode))
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "metadata not support! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_MIRROR_PKT:
            if(1 != glb_acl_prop.l2l3_key_u2_mode)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l2l3_key_u2_mode must be 1! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_IP_FRAG:
            if(0 != glb_acl_prop.l2l3_key_u2_mode)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l2l3_key_u2_mode must be 0! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_IP_OPTIONS:
        case CTC_FIELD_KEY_TCP_FLAGS:
        case CTC_FIELD_KEY_TCP_ECN:
        case CTC_FIELD_KEY_DISCARD:
        case CTC_FIELD_KEY_CTAG_COS:
        case CTC_FIELD_KEY_CTAG_CFI:
            if(0 != glb_acl_prop.l2l3_key_u2_mode && 1 != glb_acl_prop.l2l3_key_u2_mode)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l2l3_key_u2_mode must be 0 or 1! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_CPU_REASON_ID:
        case CTC_FIELD_KEY_IP_PKT_LEN_RANGE:
        case CTC_FIELD_KEY_L4_DST_PORT_RANGE:
        case CTC_FIELD_KEY_L4_SRC_PORT_RANGE:
            if (0 != glb_acl_prop.l2l3_key_u3_mode )
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l2l3_key_u2_mode must be 0! \n");
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_SRC_GPORT:
        case CTC_FIELD_KEY_STK_HDR_EXIST:
            if (glb_acl_prop.l2l3_key_u3_mode != 1)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l2l3_key_u3_mode must be: %d  \n",1);
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_FID:
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "egress not support! \n");
            return CTC_E_NOT_SUPPORT;
            break;
        case CTC_FIELD_KEY_SRC_CID:
            if(2 != glb_acl_prop.l2l3_key_u3_mode)
            {
                if (pe->key_port_mode==1)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key_port_mode : %d! \n", pe->key_port_mode);
                    return CTC_E_NOT_SUPPORT;
                }
                if (!glb_acl_prop.key_cid_en||(glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_DST))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "cid not support! \n");
                    return CTC_E_NOT_SUPPORT;
                }
            }
            break;
        default:
            break;
        }
    }
    if (DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS) && mac_ipv6_key)
    {
        switch(key_field->type)
        {
        case CTC_FIELD_KEY_METADATA:
            if (2 != glb_acl_prop.mac_ipv6_key_u0_mode && 2 != glb_acl_prop.mac_ipv6_key_u1_mode)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u0_mode is: %d! \n", 2);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "or mac_ipv6_key_u1_mode is: %d! \n", 2);
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_INTERFACE_ID:
        case CTC_FIELD_KEY_L4_TYPE:
            if (0 != glb_acl_prop.mac_ipv6_key_u1_mode)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u1_mode must be: %d! \n", 0);
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_L2_TYPE:
        case CTC_FIELD_KEY_IP_PKT_LEN_RANGE:
        case CTC_FIELD_KEY_L4_SRC_PORT_RANGE:
        case CTC_FIELD_KEY_L4_DST_PORT_RANGE:
            if (0 != glb_acl_prop.mac_ipv6_key_u0_mode)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u0_mode must be: %d! \n", 0);
                return CTC_E_NOT_SUPPORT;
            }
            break;

        case CTC_FIELD_KEY_SRC_CID:
            if(1 == pe->key_port_mode && 1 != glb_acl_prop.mac_ipv6_key_u0_mode)
            {
                return CTC_E_PARAM_CONFLICT;
            }
            if (!(1 == glb_acl_prop.mac_ipv6_key_u0_mode || (glb_acl_prop.key_cid_en && (glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_SRC_DST || glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_SRC))))
            {
                return CTC_E_NOT_SUPPORT;
            }
            break;
        case CTC_FIELD_KEY_DST_CID:
            if(1 == pe->key_port_mode && 1 != glb_acl_prop.mac_ipv6_key_u1_mode)
            {
                return CTC_E_PARAM_CONFLICT;
            }
            if (!(1 == glb_acl_prop.mac_ipv6_key_u1_mode || (glb_acl_prop.key_cid_en && (glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_SRC_DST || glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_DST))))
            {
                return CTC_E_NOT_SUPPORT;
            }
            break;
        }
    }
    if (DRV_FROM_TMM(lchip) && (dir==CTC_EGRESS))
    {
        switch(key_field->type)
        {
        case CTC_FIELD_KEY_PRIORITY:
            CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
            break;
        case CTC_FIELD_KEY_NPM_IM_FLOW_ID:
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFFF);
            break;
        case CTC_FIELD_KEY_NPM_IM_L_FLAG:
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
            break;
        }
    }
    return CTC_E_NONE;

}

 /*delete: all fields(many to one) can't reset to 0;if reset to 0,other fields have problems*/
int32
_sys_usw_acl_set_tcam_key_union(uint8 lchip, ctc_field_key_t* key_field, sys_acl_entry_t* pe, uint8 is_add)
{
    uint8 mac_key = 0;
    uint8 mac_l3_basic_key = 0;
    uint8 fwd_ext_key = 0;
    uint8 udf_key = 0;
    uint8 mac_l3_key = 0;
    uint8 mac_ipv6_key = 0;
    ctc_global_acl_property_t glb_acl_prop;

    sal_memset(&glb_acl_prop, 0, sizeof(ctc_global_acl_property_t));
    fwd_ext_key =  pe->key_type == CTC_ACL_KEY_FWD_EXT;
    mac_key = pe->key_type == CTC_ACL_KEY_MAC;
    mac_l3_basic_key = pe->key_type == CTC_ACL_KEY_MAC_IPV4;
    udf_key = pe->key_type == CTC_ACL_KEY_UDF;
    mac_l3_key = pe->key_type == CTC_ACL_KEY_MAC_IPV4;
    mac_ipv6_key = pe->key_type == CTC_ACL_KEY_MAC_IPV6;

    switch(key_field->type)
    {
     case CTC_FIELD_KEY_L2_TYPE:
        pe->l2_type = is_add?key_field->data:0;
        break;
     case  CTC_FIELD_KEY_L3_TYPE:
        pe->l3_type = is_add?key_field->data:0;
        break;
     case  CTC_FIELD_KEY_L4_TYPE:
        pe->l4_type = is_add?key_field->data:0;
        break;
     case CTC_FIELD_KEY_L4_USER_TYPE:
        pe->l4_user_type = is_add?key_field->data:0;
        break;
    case CTC_FIELD_KEY_PORT:
        {
            ctc_field_port_t* p_field_port = (ctc_field_port_t*)key_field->ext_data;
            if(p_field_port->type == CTC_FIELD_PORT_TYPE_PORT_BITMAP || p_field_port->type == CTC_FIELD_PORT_TYPE_GPORT || p_field_port->type == CTC_FIELD_PORT_TYPE_LOGIC_PORT)
            {
                pe->key_port_mode = udf_key? pe->key_port_mode: (is_add ? 1 :0);
            }
            if (DRV_FROM_TMM(lchip) && mac_ipv6_key)
            {
                pe->key_port_mode = (is_add ? 1 :0);
            }
        }
        break;
    case CTC_FIELD_KEY_METADATA:
        if (!DRV_FROM_TMM(lchip))
        {
            pe->key_port_mode = udf_key? pe->key_port_mode: (is_add ? 2 :0);
        }
        break;
    case CTC_FIELD_KEY_SRC_CID:
        glb_acl_prop.dir = CTC_EGRESS;
        glb_acl_prop.lkup_level = pe->group->group_info.block_id;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &glb_acl_prop, 1));
        pe->key_port_mode = (is_add ? (((mac_l3_key && glb_acl_prop.l2l3_key_u3_mode != 2) ||(mac_ipv6_key && glb_acl_prop.mac_ipv6_key_u0_mode != 1))? 2 : pe->key_port_mode) :0);
        break;
    case CTC_FIELD_KEY_DST_CID:
        glb_acl_prop.dir = CTC_EGRESS;
        glb_acl_prop.lkup_level = pe->group->group_info.block_id;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &glb_acl_prop, 1));
        pe->key_port_mode = (is_add ? (((mac_l3_key && glb_acl_prop.l2l3_key_u2_mode != 2) ||(mac_ipv6_key && glb_acl_prop.mac_ipv6_key_u1_mode != 1))? 2 : pe->key_port_mode):0);
        
        break;
    case CTC_FIELD_KEY_STAG_VALID:               /**< [D2] S-Vlan Exist. */
    case CTC_FIELD_KEY_SVLAN_ID:                 /**< [D2] S-Vlan ID. */
    case CTC_FIELD_KEY_STAG_COS:                 /**< [D2] Stag Cos. */
    case CTC_FIELD_KEY_STAG_CFI:                 /**< [D2] Stag Cfi. */
    case CTC_FIELD_KEY_SVLAN_RANGE:              /**< [D2] Svlan Range;
        data: min, mask: max, ext_data: (uint32*)vrange_gid. */
        if (mac_key)
        {
            pe->mac_key_vlan_mode =  1;  /*delete can't reset to 0*/
        }
        break;
    case CTC_FIELD_KEY_CTAG_VALID:               /**< [D2] C-Vlan Exist. */
    case CTC_FIELD_KEY_CVLAN_ID:                 /**< [D2] C-Vlan ID. */
    case CTC_FIELD_KEY_CTAG_COS:                 /**< [D2] Ctag Cos. */
    case CTC_FIELD_KEY_CTAG_CFI:                 /**< [D2] Ctag Cfi. */
    case CTC_FIELD_KEY_CVLAN_RANGE:              /**< [D2] Cvlan Range;
        data: min, mask: max, ext_data: (uint32*)vrange_gid. */
        if (mac_key)
        {
            pe->mac_key_vlan_mode = 2;
        }
        if (mac_l3_basic_key)
        {
            pe->macl3basic_key_cvlan_mode = 1;
        }
        break;
    case CTC_FIELD_KEY_MAC_DA:
        if (mac_l3_basic_key)
        {
            pe->macl3basic_key_macda_mode = is_add ? 1:0;
        }
        break;
    case CTC_FIELD_KEY_NSH_CBIT:                 /**< [D2] C-bit of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_OBIT:                 /**< [D2] O-bit of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_NEXT_PROTOCOL:        /**< [D2] Next Protocol of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_SI:                  /**< [D2] Service Index of the Network Service Header. */
    case CTC_FIELD_KEY_NSH_SPI:                 /**< [D2] Service Path ID of the Network Service Header. */
        if (fwd_ext_key)
        {
            pe->fwd_key_nsh_mode = 1;
        }
        break;
    case CTC_FIELD_KEY_IPV6_SA:                  /**< [D2] Source IPv6 Address. */
		break;
    case  CTC_FIELD_KEY_IPV6_DA:                  /**< [D2] Destination IPv6 Address. */
		break;
    case CTC_FIELD_KEY_UDF:
    case CTC_FIELD_KEY_UDF_AD_ID:
        if (fwd_ext_key)
        {
            pe->fwd_key_nsh_mode = is_add ?2 :0;
        }
        break;
    case CTC_FIELD_KEY_GRE_KEY:                     /**< [D2] Gre Key. */
    case CTC_FIELD_KEY_NVGRE_KEY:
        pe->key_l4_port_mode = is_add ?3 :0; /*gre*/
        break;
    case CTC_FIELD_KEY_VN_ID:
        pe->key_l4_port_mode = is_add ?2 :0; /*vxlan*/
        break;
    case CTC_FIELD_KEY_ICMP_CODE:
    case CTC_FIELD_KEY_ICMP_TYPE:
    case CTC_FIELD_KEY_IGMP_TYPE:
    case CTC_FIELD_KEY_L4_DST_PORT:
    case CTC_FIELD_KEY_L4_SRC_PORT:
    case CTC_FIELD_KEY_TCP_ECN:
    case CTC_FIELD_KEY_TCP_FLAGS:
        if (DRV_FROM_TMM(lchip)&&
            (key_field->type!=CTC_FIELD_KEY_TCP_ECN)&&
            (key_field->type!=CTC_FIELD_KEY_TCP_FLAGS))
        {
            pe->key_l4_port_mode = 0;
        }
        else
        {
            pe->key_l4_port_mode = is_add ? 1 : 0; /*l4port*/
        }
        break;

    case CTC_FIELD_KEY_WLAN_CTL_PKT:
    case CTC_FIELD_KEY_WLAN_RADIO_MAC:
    case CTC_FIELD_KEY_WLAN_RADIO_ID:
        pe->key_mergedata_mode = 1;
        break;
    case CTC_FIELD_KEY_AWARE_TUNNEL_INFO:
        pe->key_mergedata_mode = is_add ?2 :0;
        if (mac_l3_basic_key)
        {
            pe->macl3basic_key_macda_mode = is_add ? 2:0;
            pe->macl3basic_key_cvlan_mode = is_add ? 2:0;
        }
        break;
    case CTC_FIELD_KEY_VXLAN_RSV1:
    case CTC_FIELD_KEY_VXLAN_RSV2:
        if (CTC_ACL_KEY_IPV6_EXT == pe->key_type || CTC_ACL_KEY_MAC_IPV6 == pe->key_type)
        {
            pe->key_mergedata_mode = 1;
        }
        break;
    case CTC_FIELD_KEY_IS_Y1731_OAM:
        pe->l3_type = is_add?((pe->l3_type == CTC_PARSER_L3_TYPE_MPLS || pe->l3_type == CTC_PARSER_L3_TYPE_MPLS_MCAST)?\
                                pe->l3_type : CTC_PARSER_L3_TYPE_MPLS):0;
        break;
    case CTC_FIELD_KEY_CLASS_ID:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_CLASS_ID, is_add);
        break;
    default:
        break;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_get_compress_ipv6_addr(uint8 lchip,sys_acl_entry_t* pe,uint8 is_da, ipv6_addr_t ipv6, ipv6_addr_t ipv6_64)
{
    ctc_global_acl_property_t acl_property;
    uint8 compress_mode = 0;
    uint8 index = 0;
    uint64 ipv6_temp[4] = {0};

    sal_memset(&acl_property,0,sizeof(ctc_global_acl_property_t));
    acl_property.dir = pe->group->group_info.dir;
    acl_property.lkup_level = pe->group->group_info.block_id;

    CTC_ERROR_DUMP(sys_usw_get_glb_acl_property(lchip, &acl_property, 1));
    if (pe->key_type == CTC_ACL_KEY_IPV6
        || pe->key_type == CTC_ACL_KEY_FWD)
    {
        compress_mode =  is_da ? acl_property.key_ipv6_da_addr_mode:acl_property.key_ipv6_sa_addr_mode;
    }
    else if(pe->key_type == CTC_ACL_KEY_CID)
    {
        compress_mode =  is_da ? acl_property.cid_key_ipv6_da_addr_mode:acl_property.cid_key_ipv6_sa_addr_mode;
    }
    else
    { /*no compress*/
        sal_memcpy(ipv6_64, ipv6, sizeof(ipv6_addr_t));
        return CTC_E_NONE;
    }

    sal_memset(ipv6_64, 0, sizeof(ipv6_addr_t));
    index = compress_mode;
    compress_mode = compress_mode > 8 ? (compress_mode - 8) : compress_mode;
    ipv6_temp[0] = ipv6[index/9];
    ipv6_temp[1] = ipv6[(index/9)+1];
    ipv6_temp[2] = ipv6[(index/9)+2];

    ipv6_64[0] = ((ipv6_temp[0]<< (compress_mode*4))& (~((1LLU<<(compress_mode*4))-1))) | ((ipv6_temp[1] >> (32-(compress_mode*4))) & ((1LLU<<(compress_mode*4))-1)) ;
    ipv6_64[1] = ((ipv6_temp[1]<< (compress_mode*4))& (~((1LLU<<(compress_mode*4))-1))) | ((ipv6_temp[2] >> (32-(compress_mode*4))) & ((1LLU<<(compress_mode*4))-1)) ;
    return CTC_E_NONE;
}

int32
_sys_usw_acl_get_ipv6_addr_from_compress(uint8 lchip,sys_acl_entry_t* pe,uint8 is_da, ipv6_addr_t in_ipv6_64, ipv6_addr_t out_ipv6_128)
{
    ctc_global_acl_property_t acl_property;
    uint8 compress_mode = 0;
    uint8 index = 0;
    uint64 ipv6_temp[2] = {0};

    sal_memset(&acl_property,0,sizeof(ctc_global_acl_property_t));

    acl_property.dir = pe->group->group_info.dir;
    acl_property.lkup_level = pe->group->group_info.block_id;

    CTC_ERROR_DUMP(sys_usw_get_glb_acl_property(lchip, &acl_property, 1));
    if (pe->key_type == CTC_ACL_KEY_IPV6
        || pe->key_type == CTC_ACL_KEY_FWD)
    {
        compress_mode =  is_da ? acl_property.key_ipv6_da_addr_mode:acl_property.key_ipv6_sa_addr_mode;
    }
    else if(pe->key_type == CTC_ACL_KEY_CID)
    {
        compress_mode =  is_da ? acl_property.cid_key_ipv6_da_addr_mode:acl_property.cid_key_ipv6_sa_addr_mode;
    }
    sal_memset(out_ipv6_128, 0, sizeof(ipv6_addr_t));
    index = compress_mode;
    compress_mode = compress_mode > 8 ? (compress_mode - 8) : compress_mode;
    ipv6_temp[0] = in_ipv6_64[0];
    ipv6_temp[1] = in_ipv6_64[1];
    out_ipv6_128[index/9]     = ((ipv6_temp[0] >> (compress_mode*4)) & (0xFFFFFFFFLLU>>(compress_mode*4)));
    out_ipv6_128[(index/9)+1] = ((ipv6_temp[0] << (32-(compress_mode*4))) & (~(0xFFFFFFFFLLU>>(compress_mode*4)))) | ((ipv6_temp[1] >> (compress_mode*4)) & (0xFFFFFFFFLLU>>(compress_mode*4)));
    out_ipv6_128[(index/9)+2] = (ipv6_temp[1] << (32-(compress_mode*4))) & (~(0xFFFFFFFFLLU>>(compress_mode*4)));
    return CTC_E_NONE;
}

/*
 * install entry to hardware table
 */
int32
_sys_usw_acl_install_entry(uint8 lchip, sys_acl_entry_t* pe, uint8 flag, uint8 move_sw)
{
    sys_acl_group_t* pg = NULL;
    sys_acl_hash_entry_t* pe_hash = ACL_SHARE_PTR(pe, sys_acl_hash_entry_t);
    uint8 installed = 0;
    if (!pe ||!pe->group)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not found \n");
        return CTC_E_NOT_EXIST;
    }
    if (ACL_ENTRY_IS_TCAM(pe))
    {
        installed = (FPA_ENTRY_FLAG_INSTALLED == pe->fpae.flag) ? TRUE : FALSE;
    }
    else
    {
        installed = pe_hash->installed ? TRUE : FALSE;
    }
    pg = pe->group;
    if (SYS_ACL_ENTRY_OP_FLAG_ADD == flag)
    {
    	if(TRUE == installed)
        {
           return CTC_E_NONE;
        }
        if(!ACL_ENTRY_IS_TCAM(pe))
        {
           /*check hw and roll back*/
           if (!pe_hash->hash_valid)
           {
               SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Hash valid is %d, Not ready to configuration \n", pe_hash->hash_valid);
               return CTC_E_NOT_READY;
           }

           CTC_ERROR_RETURN(_sys_usw_acl_get_hash_index(lchip, pe_hash, 1,1));
        }

        CTC_ERROR_RETURN(_sys_usw_acl_add_hw(lchip, pe, NULL));
        installed = TRUE;

        if (move_sw)
        {
            /* move to tail */
            ctc_list_pointer_delete(&(pg->entry_list), &(pe->head));
            ctc_list_pointer_insert_tail(&(pg->entry_list), &(pe->head));
        }
    }
    else if (SYS_ACL_ENTRY_OP_FLAG_DELETE == flag)
    {
    	if(FALSE == installed)
        {
           return CTC_E_NONE;
        }

        CTC_ERROR_RETURN(_sys_usw_acl_remove_hw(lchip, pe));
        installed = FALSE;
        if (move_sw)
        {
            /* move to head */
            ctc_list_pointer_delete(&(pg->entry_list), &(pe->head));
            ctc_list_pointer_insert_head(&(pg->entry_list), &(pe->head));
        }
    }
    if (ACL_ENTRY_IS_TCAM(pe))
    {
        pe->fpae.flag = (TRUE == installed) ? FPA_ENTRY_FLAG_INSTALLED : FPA_ENTRY_FLAG_UNINSTALLED;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_TCAM_ENTRY, 1);
    }
    else
    {
        pe_hash->installed = installed;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_HASH_ENTRY, 1);
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_BLOCK, 1);
    return CTC_E_NONE;
}

extern sys_acl_flex_key_t*
_sys_tmm_acl_get_flex_key(uint8 lchip, uint8 key_type);

extern int32
sys_tmm_acl_flex_key_alloc_ltid(uint8 lchip,
                                uint8 block_id,
                                sys_acl_flex_key_t* p_flex_key);

int32
_sys_usw_acl_check_kset(uint8 lchip, sys_acl_entry_t* pe)
{
    uint8  support_vsi_check = 0;
    uint8  fwd_ext_key_use_l2_hdr = 0;
    uint8  l3_key_share_field_mode = 0;
    uint8  fwd_ext_key_udf_use_nsh = 0;
    uint8  fwd_key_nsh_mode = 0;
    uint8  key_port_is_cid = 0;
    uint8  fwd_ext_key = 0;
    uint8  step = 0;
    uint32 cmd = 0;
    FlowTcamLookupCtl_m flow_ctl;
    sys_acl_kset_t* p_kset = NULL;
    sys_acl_fixed_key_t* p_fixed_key = ctc_vector_get(p_usw_acl_master[lchip]->fixed_key_vec, pe->key_type);
    if (NULL == p_fixed_key)
    {
        return CTC_E_INVALID_PARAM;
    }
    p_kset = &p_fixed_key->kset;
	if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        ctc_global_acl_property_t glb_acl_prop;
        sal_memset(&glb_acl_prop, 0, sizeof(ctc_global_acl_property_t));
        glb_acl_prop.dir = CTC_EGRESS;
		glb_acl_prop.lkup_level = pe->group->group_info.block_id;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &glb_acl_prop, 1));

		if (p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC)
		{
			if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_MAC_SA) && glb_acl_prop.key_stk_hdr_en != 0)
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key stk hdr enable! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_ROUTED_PKT)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_DISCARD)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_FID)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_MIRROR_PKT)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_SRC_GPORT)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_STK_HDR_EXIST)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_PRIORITY)) && (glb_acl_prop.key_stk_hdr_en == 0))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key stk hdr disable! \n");
				return CTC_E_NOT_SUPPORT;
			}
		}

		if (p_fixed_key->origin_key_type == CTC_ACL_KEY_IPV4)
		{
			if ((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_TCP_ECN) ||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_TCP_FLAGS)) && (glb_acl_prop.key_stk_hdr_en != 0))
			{
	            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key stk hdr enable! \n");
	            return CTC_E_INVALID_PARAM;
			}
			if((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_DISCARD)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_MIRROR_PKT)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_STK_HDR_EXIST)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_PRIORITY)) && (glb_acl_prop.key_stk_hdr_en==0))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "share fields can't be used as sh! \n");
				return CTC_E_NOT_SUPPORT;
			}
		}

		if (p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV4)
		{
			if(((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_DST_CID) && 2 != glb_acl_prop.l2l3_key_u2_mode)
				||(SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_SRC_CID)&& 2 != glb_acl_prop.l2l3_key_u3_mode)) &&
			   (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_PORT)||(SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_METADATA)
			   && 3 != glb_acl_prop.l2l3_key_u2_mode && 3 != glb_acl_prop.l2l3_key_u3_mode)))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "key_port used as port or metadata! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if ((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_DST_CID) && 2 != glb_acl_prop.l2l3_key_u2_mode)
				&& (!glb_acl_prop.key_cid_en || (glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_SRC)))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "cid not support! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if ((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_SRC_CID)&& 2 != glb_acl_prop.l2l3_key_u3_mode)
				&& (!glb_acl_prop.key_cid_en || (glb_acl_prop.key_cid_mode==CTC_GLOBAL_ACL_CID_MODE_DST)))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "cid not support! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if ((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_METADATA) && 3 != glb_acl_prop.l2l3_key_u2_mode && 3 != glb_acl_prop.l2l3_key_u3_mode)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_FID))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "metadata not support! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_IP_OPTIONS)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_TCP_FLAGS)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_TCP_ECN)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_DISCARD)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_CTAG_COS)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_CTAG_CFI)) && (0 != glb_acl_prop.l2l3_key_u2_mode) && (1 != glb_acl_prop.l2l3_key_u2_mode))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l2l3_key_u2_mode must be 0 or 1! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if(SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_IP_FRAG)&& (0 != glb_acl_prop.l2l3_key_u2_mode))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "ip frag not support! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if(SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_MIRROR_PKT)&& (1 != glb_acl_prop.l2l3_key_u2_mode))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mirror pkt not support! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_CPU_REASON_ID)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_IP_PKT_LEN_RANGE)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L4_DST_PORT_RANGE)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L4_SRC_PORT_RANGE)) && (glb_acl_prop.l2l3_key_u3_mode!=0))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "stk hdr enable! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_SRC_GPORT)||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_STK_HDR_EXIST)) && (glb_acl_prop.l2l3_key_u3_mode !=1))
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "stk hdr disable! \n");
				return CTC_E_NOT_SUPPORT;
			}
		}
		if (p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV6)
		{
			if ((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L2_TYPE) ||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L4_DST_PORT_RANGE) ||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L4_SRC_PORT_RANGE) ||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_IP_PKT_LEN_RANGE))&& 0 != glb_acl_prop.mac_ipv6_key_u0_mode)
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u0_mode must be 0 ! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if ((SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L4_TYPE) ||
				SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_INTERFACE_ID))&& 0 != glb_acl_prop.mac_ipv6_key_u1_mode)
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u1_mode must be 0 ! \n");
				return CTC_E_NOT_SUPPORT;
			}

			if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_SRC_CID) && 1 != glb_acl_prop.mac_ipv6_key_u0_mode)
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u0_mode must be 1 ! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_DST_CID) && 1 != glb_acl_prop.mac_ipv6_key_u1_mode)
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u1_mode must be 1 ! \n");
				return CTC_E_NOT_SUPPORT;
			}
			if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_METADATA) && 2 != glb_acl_prop.mac_ipv6_key_u0_mode && 2 != glb_acl_prop.mac_ipv6_key_u1_mode)
			{
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "mac_ipv6_key_u0_mode is  2! \n");
				SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "or mac_ipv6_key_u1_mode is 2! \n");
				return CTC_E_NOT_SUPPORT;
			}
		}
	}

    cmd = DRV_IOR(FlowTcamLookupCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &flow_ctl);

    if (CTC_INGRESS == pe->group->group_info.dir)
    {
        step = FlowTcamLookupCtl_gIngrAcl_1_categoryIdFieldValid_f - FlowTcamLookupCtl_gIngrAcl_0_categoryIdFieldValid_f;
        key_port_is_cid = GetFlowTcamLookupCtl(V, gIngrAcl_0_categoryIdFieldValid_f + step *  pe->group->group_info.block_id, &flow_ctl);
        step = FlowTcamLookupCtl_gIngrAcl_1_l3Key160ShareFieldType_f - FlowTcamLookupCtl_gIngrAcl_0_l3Key160ShareFieldType_f;
        l3_key_share_field_mode = GetFlowTcamLookupCtl(V,gIngrAcl_0_l3Key160ShareFieldType_f + step * pe->group->group_info.block_id, &flow_ctl);
    }
    else
    {
        step = FlowTcamLookupCtl_gEgrAcl_1_l3Key160ShareFieldType_f - FlowTcamLookupCtl_gEgrAcl_0_l3Key160ShareFieldType_f;
        l3_key_share_field_mode = GetFlowTcamLookupCtl(V,gEgrAcl_0_l3Key160ShareFieldType_f + step * pe->group->group_info.block_id, &flow_ctl);
    }
    fwd_ext_key =  p_fixed_key->origin_key_type == CTC_ACL_KEY_FWD_EXT;
    support_vsi_check = (SYS_GET_CHIP_VERSION != SYS_CHIP_SUB_VERSION_A && DRV_IS_TSINGMA(lchip)) ? 1 : 0;
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_FID))
    {
        if (support_vsi_check && (p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV4 || p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV6))
        {
            step = FlowTcamLookupCtl_gIngrAcl_1_aclL2L3KeySupportVsi_f - FlowTcamLookupCtl_gIngrAcl_0_aclL2L3KeySupportVsi_f;
            if (0 == GetFlowTcamLookupCtl(V, gIngrAcl_0_aclL2L3KeySupportVsi_f + step * pe->group->group_info.block_id , &flow_ctl))
            {
                return CTC_E_NOT_SUPPORT;
            }
        }
    }
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_METADATA))
    {
        SYS_ACL_METADATA_CHECK(pe->group->group_info.type);
        if (!DRV_FROM_TMM(lchip) && key_port_is_cid)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Key Port check conflict, key_is_cid:%d \n", key_port_is_cid);
            return CTC_E_PARAM_CONFLICT;
        }
    }
    fwd_ext_key_use_l2_hdr = !(GetFlowTcamLookupCtl(V,forwardingAclKeyUnion1Type_f,&flow_ctl) & (1 << pe->group->group_info.block_id));
    fwd_ext_key_udf_use_nsh = GetFlowTcamLookupCtl(V,forceForwardingAclKeyUseNsh_f,&flow_ctl) & (1 << (pe->group->group_info.block_id));
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_MAC_SA) || SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_MAC_DA))
    {
        if (p_fixed_key->origin_key_type == CTC_ACL_KEY_FWD_EXT && fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d \n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
    }

    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_STAG_VALID)   ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_SVLAN_ID)     ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_STAG_COS)     ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_STAG_CFI)     ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_SVLAN_RANGE))
    {
        if (p_fixed_key->origin_key_type == CTC_ACL_KEY_FWD_EXT && !fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d \n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
    }

    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_CVLAN_ID)   ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_CTAG_COS)   ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_CVLAN_RANGE))
    {
        if ( support_vsi_check && ((p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV4) || (p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV6)) )
        {
            step = FlowTcamLookupCtl_gIngrAcl_1_aclL2L3KeySupportVsi_f - FlowTcamLookupCtl_gIngrAcl_0_aclL2L3KeySupportVsi_f;
            if (1 == GetFlowTcamLookupCtl(V, gIngrAcl_0_aclL2L3KeySupportVsi_f + step * pe->group->group_info.block_id , &flow_ctl))
            {
                return CTC_E_NOT_SUPPORT;
            }
        }
        if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_CTAG_VALID) ||
		    SYS_ACL_PKSET_TEST(p_kset,  CTC_FIELD_KEY_CTAG_CFI))
		{
		    if (fwd_ext_key && !fwd_ext_key_use_l2_hdr)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d \n", fwd_ext_key_use_l2_hdr);
                return CTC_E_INVALID_PARAM;
            }
		}
    }

    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_IP_TTL))
    {
        if (p_fixed_key->origin_key_type == CTC_ACL_KEY_IPV4 && (l3_key_share_field_mode != 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode :%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
    }
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_IP_DSCP))
    {
        if (!DRV_FROM_TMM(lchip) && p_fixed_key->origin_key_type == CTC_ACL_KEY_IPV4 && ((l3_key_share_field_mode == 0 &&\
            GetFlowTcamLookupCtl(V,l3Key160FullRangeBitMapMode_f, &flow_ctl)) || l3_key_share_field_mode == 3  ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode :%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
    }
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_IP_PKT_LEN_RANGE)     ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L4_DST_PORT_RANGE)    ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_L4_SRC_PORT_RANGE))
    {
        if (p_fixed_key->origin_key_type == CTC_ACL_KEY_IPV4 && (l3_key_share_field_mode != 0   ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode :%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
    }
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_TCP_ECN) ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_TCP_FLAGS))
    {
        if (!DRV_FROM_TMM(lchip) && p_fixed_key->origin_key_type == CTC_ACL_KEY_IPV4 && (l3_key_share_field_mode != 2   ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key share_field_mode:%d \n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
    }
    fwd_key_nsh_mode |= (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_CBIT)             ||
                         SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_OBIT)             ||
                         SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_NEXT_PROTOCOL)    ||
                         SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_SI)               ||
                         SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_SPI))?1:0;
    fwd_key_nsh_mode |= (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_UDF) || SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_UDF_AD_ID))?2:0;
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_CBIT)             ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_OBIT)             ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_NEXT_PROTOCOL)    ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_SI)               ||
        SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_NSH_SPI))
    {
        /*forwarding ext key:nsh and udf is union*/
        if (p_fixed_key->origin_key_type == CTC_ACL_KEY_FWD_EXT && fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr :%d\n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && !fwd_ext_key_udf_use_nsh)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key udf_use_nsh :%d\n", fwd_ext_key_udf_use_nsh);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && fwd_ext_key_udf_use_nsh
            && fwd_key_nsh_mode != 1 && fwd_key_nsh_mode != 0)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key udf_use_nsh :%d\n", fwd_ext_key_udf_use_nsh);
            return CTC_E_INVALID_PARAM;
        }
    }
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_UDF) || SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_UDF_AD_ID))
    {
        if (p_fixed_key->origin_key_type == CTC_ACL_KEY_FWD_EXT && fwd_ext_key_use_l2_hdr)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key use_l2_hdr:%d\n", fwd_ext_key_use_l2_hdr);
            return CTC_E_INVALID_PARAM;
        }
        if (fwd_ext_key && fwd_ext_key_udf_use_nsh
            && fwd_key_nsh_mode != 2 && fwd_key_nsh_mode != 0)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "fwd_ext_key udf_use_nsh:%d,fwd_key_nsh_mode:%d\n", fwd_ext_key_udf_use_nsh, fwd_key_nsh_mode);
            return CTC_E_INVALID_PARAM;
        }
    }
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_AWARE_TUNNEL_INFO))
    {
        if ( support_vsi_check && ((p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV4) || (p_fixed_key->origin_key_type == CTC_ACL_KEY_MAC_IPV6)) )
        {
            step = FlowTcamLookupCtl_gIngrAcl_1_aclL2L3KeySupportVsi_f - FlowTcamLookupCtl_gIngrAcl_0_aclL2L3KeySupportVsi_f;
            if (1 == GetFlowTcamLookupCtl(V, gIngrAcl_0_aclL2L3KeySupportVsi_f + step * pe->group->group_info.block_id , &flow_ctl))
            {
                return CTC_E_NOT_SUPPORT;
            }
        }
    }
    if (SYS_ACL_PKSET_TEST(p_kset, CTC_FIELD_KEY_VRFID))
    {
        if (p_fixed_key->origin_key_type == CTC_ACL_KEY_IPV4 && (l3_key_share_field_mode != 3  ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3_key share_field_mode:%d\n", l3_key_share_field_mode);
            return CTC_E_INVALID_PARAM;
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_add_hash_entry(uint8 lchip, sys_acl_hash_entry_t* pe)
{
    sys_acl_flex_hash_t* fk = ACL_SHARE_PTR(pe->ua->buffer.fk, sys_acl_flex_hash_t);
    uint32 value = 0;
    uint8  key_type = pe->key_type;
    uint8  sys_key_type = 0;

    CTC_ERROR_RETURN(_sys_usw_acl_check_entry_cnt(lchip, (sys_acl_entry_t*)pe));
    if (!fk || 0 == pe->group->group_info.block_id)/* flow hash or flex hash0 */
    {
        CTC_ERROR_RETURN(_sys_usw_acl_add_hash_key_common_field(lchip, pe));
        CTC_ERROR_RETURN(_sys_usw_acl_set_hash_sel_bmp(lchip,pe));
        CTC_ERROR_RETURN(_sys_usw_acl_add_hash_entry_db(lchip, pe->group, pe));
        if(fk && SYS_ACL_KEY_IS_FLEX_HASH0(pe->action_type, pe->key_type, pe->group->group_info.block_id))
        {
            key_type = fk->origin_key_type;
            fk->entry_count[pe->group->group_info.block_id]++;
        }
        CTC_ERROR_RETURN(sys_usw_acl_map_ctc_to_sys_hash_key_type(key_type,&sys_key_type));
         _sys_usw_acl_update_key_count(lchip, (void*)pe, 1);
        p_usw_acl_master[lchip]->hash_sel_profile_count[sys_key_type][pe->hash_field_sel_id]++;
    }
    else
    {
        CTC_MAX_VALUE_CHECK(pe->group->group_info.block_id, ACL_HASH_MAX_NUM-1);
        if (!DRV_TABLE_MAX_INDEX(lchip, DsXLookup1HashKey_t) && pe->group->group_info.block_id == 2)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "DsXLookup1HashKey never alloed by ftm!\n");
            return CTC_E_NO_RESOURCE;
        }
        if(pe->group->group_info.block_id > 0 && !fk->presel_cnt)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "XLookup presel not ready!\n");
            return CTC_E_INVALID_CONFIG;
        }
        value = fk->hash_type;
        sal_memcpy(&pe->ua->buffer.kset, &fk->kset, sizeof(fk->kset));

        if (pe->group->group_info.block_id == 2)
        {
            SetDsXLookup1HashKey(V, hashType_f, pe->ua->buffer.key, value);
            SetDsXLookup1HashKey(V, adPri_f, pe->ua->buffer.key, p_usw_acl_master[lchip]->xflow_ad_couple ? 1 : pe->priority);
        }
        else if((pe->group->group_info.block_id == 1))
        {
            SetDsXLookup0HashKey(V, hashType_f, pe->ua->buffer.key, value);
            SetDsXLookup0HashKey(V, adPri_f, pe->ua->buffer.key, p_usw_acl_master[lchip]->xflow_ad_couple ? 1 : pe->priority);
        }

        /*add xkey common field end*/
        CTC_ERROR_RETURN(_sys_usw_acl_add_hash_entry_db(lchip, pe->group, pe));
        fk->entry_count[pe->group->group_info.block_id]++;
    }

    /*build group info*/
	_sys_usw_acl_add_group_key_port_field(lchip,pe->entry_id,pe->group);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_HASH_ENTRY, 1);

    return CTC_E_NONE;
}

int32
_sys_usw_acl_remove_entry_hash(uint8 lchip, sys_acl_hash_entry_t* pe)
{
    sys_acl_flex_hash_t* fk = NULL;
    ctc_acl_field_action_t action_field;
    uint8 sys_key_type = 0;
    uint8 block_id = pe->group->group_info.block_id;

    /*reset action to default ,free resource*/
    sal_memset(&action_field,0,sizeof(action_field));
    action_field.type = CTC_ACL_FIELD_ACTION_CANCEL_ALL;

    block_id = (CTC_INGRESS == pe->group->group_info.dir ? block_id : block_id + ACL_IGS_BLOCK_MAX_NUM);
    fk = (void*)pe->ua->buffer.fk;
    CTC_ERROR_RETURN(_sys_usw_acl_add_dsflow_field(lchip, &action_field, pe, 1));
    CTC_ERROR_RETURN(_sys_usw_acl_remove_hash_entry(lchip, pe, pe->group, &p_usw_acl_master[lchip]->block[block_id]));
    if (fk)
    {
        fk->entry_count[pe->group->group_info.block_id]--;
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_acl_map_ctc_to_sys_hash_key_type(pe->key_type, &sys_key_type));
        if (p_usw_acl_master[lchip]->hash_sel_profile_count[sys_key_type][pe->hash_field_sel_id] > 0)
        {
            p_usw_acl_master[lchip]->hash_sel_profile_count[sys_key_type][pe->hash_field_sel_id]--;
        }
    }
    /* memory free */
    _sys_usw_acl_remove_aset(lchip, pe->aset_id);

    mem_free(pe);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_HASH_ENTRY, 1);
    return CTC_E_NONE;
}

int32
_sys_usw_acl_add_tcam_entry(uint8 lchip, uint8 priority_valid, sys_acl_entry_t* pe)
{
    sys_acl_block_t* p_acb = NULL;
    sys_acl_league_t* p_league = NULL;
    uint8 block_id = pe->group->group_info.block_id;
    uint8 key_size = 0;
    int32 ret = CTC_E_NONE;

    CTC_ERROR_RETURN(_sys_usw_acl_check_entry_cnt(lchip, pe));
    if (CTC_EGRESS == pe->group->group_info.dir)
    {
        block_id += p_usw_acl_master[lchip]->igs_block_num;
    }

    p_league = &(p_usw_acl_master[lchip]->league[block_id]);
    if(p_league->lkup_level_bitmap == 0)
    {
       return CTC_E_NO_RESOURCE;
    }

    p_acb = &SYS_ACL_BLOCK(lchip, block_id);
    if (SYS_USW_ACL_UPA_EN(lchip, pe->group->group_info.dir))
    {
        if (!priority_valid)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Acl priority(index) is %u\n", pe->fpae.priority);
            return CTC_E_INVALID_PARAM;
        }
        if (pe->fpae.priority >= p_acb->fpab.entry_count)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Acl tcam key index exceed the max index\n");
            return CTC_E_EXCEED_MAX_SIZE;
        }
    }
    /*fixed tcam key*/
    if (!pe->ua->buffer.fk || pe->ua->buffer.fk->node_type == SYS_ACL_FLEX_KEY_NODE_FIXED)
    {
        uint16 temp_index = 0;
        uint8  temp_key_size = 0;
        uint8  step = 0;

        if(pe->ua->buffer.fk)
        {
            CTC_ERROR_RETURN(_sys_usw_acl_check_kset(lchip, pe));
        }

        key_size = _sys_usw_acl_get_key_size(lchip, 0, pe, &step);
        if(_sys_usw_acl_get_key_size(lchip, 1, pe, NULL) > key_size)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The current entry's key size can't exceed the group's max key size.\n");
            return CTC_E_INVALID_PARAM;
        }

        if (SYS_USW_ACL_UPA_EN(lchip, pe->group->group_info.dir))
        {
            if(pe->fpae.priority%step != 0)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Acl priority(index) is %u, key type is %u, the step is %u\n", \
                                                    pe->fpae.priority, pe->key_type, step);
                return CTC_E_INVALID_PARAM;
            }
            for(temp_index = pe->fpae.priority; temp_index < pe->fpae.priority+step; temp_index++)
            {
                if(!SYS_USW_ACL_UPA_EN(lchip, pe->group->group_info.dir))
                {
                    continue;
                }
                if(p_acb->fpab.entries[temp_index])
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Acl tcam key index already used, used index is %u,line:%d\n",temp_index,__LINE__);
                    return CTC_E_IN_USE;
                }
            }
            for(temp_key_size = key_size; temp_key_size < CTC_FPA_KEY_SIZE_NUM; temp_key_size++)
            {
                step = 1<<temp_key_size;
                temp_index = pe->fpae.priority/step*step;
                if(p_acb->fpab.entries[temp_index] && p_acb->fpab.entries[temp_index]->step == step)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Acl tcam key index already used, line:%d\n", __LINE__);
                    return CTC_E_IN_USE;
                }
            }
        }
    }
    /*flex tcam key*/
    else
    {
        if (SYS_USW_ACL_UPA_EN(lchip, pe->group->group_info.dir))
        {
            if (p_acb->fpab.entries[pe->fpae.priority])
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Acl tcam key index already used,line:%d\n",__LINE__);
                return CTC_E_IN_USE;
            }
        }
        key_size = pe->ua->buffer.fk->key_size;
        if(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
        {
            uint32 lkup_level_bitmap = 0;
            uint32 global_pp_en_bmp = 0;

            lkup_level_bitmap = ((1 << key_size)-1) << pe->group->group_info.block_id;
            global_pp_en_bmp = p_usw_acl_master[SYS_PP_BASE(lchip)]->global_pp_en_bmp[pe->group->group_info.dir];
            if((lkup_level_bitmap&global_pp_en_bmp) && (lkup_level_bitmap != (lkup_level_bitmap&global_pp_en_bmp)))
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Global acl bmp is conflict, current is 0x%x,line:%d\n",lkup_level_bitmap&global_pp_en_bmp,__LINE__);
                return CTC_E_NOT_READY;
            }
        }
        CTC_ERROR_RETURN(MCHIP_ACL(lchip)->expand_link_block(lchip, p_acb, pe->ua->buffer.fk, key_size));
    }

    CTC_ERROR_GOTO(_sys_usw_acl_add_key_common_field_group_none(lchip, pe), ret, clean_up);

    CTC_ERROR_GOTO(_sys_usw_acl_add_tcam_entry_db(lchip, pe->group, pe), ret, clean_up);

    /*build group info*/
	_sys_usw_acl_add_group_key_port_field(lchip,pe->fpae.entry_id,pe->group);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_TCAM_ENTRY, 1);

    return CTC_E_NONE;
clean_up:
    if (pe->ua->buffer.fk && pe->ua->buffer.fk->node_type != SYS_ACL_FLEX_KEY_NODE_FIXED)
    {
        MCHIP_ACL(lchip)->compress_link_block(lchip, p_acb, pe->ua->buffer.fk);
    }
    return ret;
}

int32
_sys_usw_acl_operate_aset(uint8 lchip, ctc_acl_aset_t* ctc_aset, uint8 action_type, sys_acl_aset_t** p_out)
{
    uint8 aset_id = 0;
    uint8 pp_base = drv_vchip_get_pp_base(lchip);
    ctc_acl_aset_t zeros;
    if(pp_base != lchip)
    {
        lchip = pp_base;
    }

    sal_memset(&zeros, 0, sizeof(ctc_acl_aset_t));

    if(ctc_aset && 0 != sal_memcmp(ctc_aset, &zeros, sizeof(ctc_acl_aset_t)))
    {
        if(ctc_aset->aset_id)
        {
            CTC_ERROR_RETURN(_sys_usw_acl_get_aset(lchip, ctc_aset->aset_id, p_out));
            if(action_type != (*p_out)->type)
            {
                return CTC_E_INVALID_CONFIG;
            }
        }
        else
        {
            CTC_ERROR_RETURN(_sys_usw_acl_add_aset(lchip, action_type, ctc_aset, p_out));
        }
    }
    else /* def aset */
    {
        aset_id = action_type ? (action_type + SYS_ACL_ASET_MAX) : 0;
        aset_id = ( DRV_IS_TSINGMA(lchip) && action_type == SYS_ACL_ACTION_TCAM_EGRESS ) ? 0 : aset_id;
        aset_id = p_usw_acl_master[lchip]->no_aset ? 0 : aset_id;
        CTC_ERROR_RETURN(_sys_usw_acl_get_aset(lchip, aset_id, p_out));
    }
    (*p_out)->ref_cnt++;
    return CTC_E_NONE;
}

int32
_sys_usw_acl_add_entry(uint8 lchip, uint32 group_id, ctc_acl_entry_t* p_ctc_entry)
{
    sys_acl_group_t* pg_lkup = NULL;
    sys_acl_hash_entry_t* pe = NULL;
    sys_acl_flex_key_t* fk = NULL;
    void* buffer = NULL;
    sys_acl_aset_t* aset = NULL;
    ctc_acl_aset_t ctc_aset;
    ctc_acl_aset_t* p_aset = NULL;
    int32 ret = CTC_E_NONE;
    uint8 is_tcam = FALSE;
    uint8 action_type = 0;

    /* check sys group, if group not exist return*/
    _sys_usw_acl_get_group_by_gid(lchip, group_id, &pg_lkup);
    if (!pg_lkup)
    {
        return CTC_E_NOT_EXIST;
    }

    /* check sys entry, if entry exist return */
    _sys_usw_acl_get_entry_by_eid(lchip, p_ctc_entry->entry_id, (void*)&pe);
    if (NULL != pe)
    {
        return CTC_E_EXIST;
    }

    CTC_ERROR_RETURN(sys_usw_acl_check_entry_type(lchip, group_id, pg_lkup, p_ctc_entry));

    if ((SYS_ACL_GROUP_IS_PRESEL(pg_lkup) && ACL_KEY_IS_TCAM(p_ctc_entry->key_type))
        || (SYS_ACL_KEY_IS_FLEX(p_ctc_entry->key_type)))
    {
        if (!SYS_ACL_GROUP_IS_PRESEL(pg_lkup))
        {
            fk = ctc_vector_get(p_usw_acl_master[lchip]->fixed_key_vec,p_ctc_entry->key_type);
        }
        else if (MCHIP_ACL(lchip)->get_flex_key)
        {
            fk = MCHIP_ACL(lchip)->get_flex_key(lchip, pg_lkup->group_info.dir, p_ctc_entry->key_type);
        }

        if (!fk)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not found flex key!!!\n");
            return CTC_E_NOT_EXIST;
        }
        is_tcam = (SYS_ACL_FLEX_KEY_NODE_HASH != fk->node_type) ? TRUE : FALSE;
    }
    else
    {
        is_tcam = ACL_KEY_IS_TCAM(p_ctc_entry->key_type) ? TRUE : FALSE;
    }
    action_type = !is_tcam ? SYS_ACL_ACTION_HASH_INGRESS : 
        ((pg_lkup->group_info.dir == CTC_INGRESS)  ? SYS_ACL_ACTION_TCAM_INGRESS : SYS_ACL_ACTION_TCAM_EGRESS);
    
    buffer = mem_malloc(MEM_ACL_MODULE, sizeof(sys_acl_buffer_t));
    if (!buffer)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(buffer,0,sizeof(sys_acl_buffer_t));
    sal_memset(&ctc_aset, 0, sizeof(ctc_aset));

    ctc_aset.aset_id = pg_lkup->aset_id;
    p_aset = (p_ctc_entry->aset || SYS_ACL_ASET_IS_DEF(pg_lkup->aset_id)) ? p_ctc_entry->aset : &ctc_aset;
    CTC_ERROR_GOTO(_sys_usw_acl_operate_aset(lchip,  p_aset, action_type, &aset), ret, free_buffer);
    /*hash entry*/
    if (!is_tcam)
    {
        if(DRV_FROM_AT(lchip) && CTC_BMP_ISSET(aset->w, CTC_ACL_FIELD_ACTION_XDATA))
        {
            CTC_ERROR_GOTO(_sys_usw_acl_check_xdata(lchip, SYS_ACL_ACTION_HASH_INGRESS, pg_lkup, aset->xdata_prof_id, aset->w, NULL), ret, free_aset);
        }
        pe = mem_malloc(MEM_ACL_MODULE, sizeof(sys_acl_hash_entry_t));
        if (!pe)
        {
            ret = CTC_E_NO_MEMORY;
            goto free_aset;
        }
        sal_memset(pe, 0, sizeof(sys_acl_hash_entry_t));
        if(fk)
        {
            if(p_ctc_entry->priority_valid)
            {
                if(p_ctc_entry->priority > ACL_XFLOW_PRIORITY_HIGHEST)
                {
                    ret = CTC_E_INVALID_PARAM;
                    goto free_pe;
                }
                pe->priority = p_ctc_entry->priority;
            }
            else
            {
                /*xlookup0 default priority 0, xlookup1 default priority 1*/
                pe->priority = (pg_lkup->group_info.block_id == 1) ? 0 : (pg_lkup->group_info.block_id == 2) ? 1 : 0;
            }
        }
        pg_lkup->group_info.bitmap_status = ACL_BITMAP_STATUS_16;
        pe->ua = (void*)buffer;
        pe->group = pg_lkup;
        pe->ua->buffer.fk = fk;
        pe->ua->buffer.aset = aset;
        pe->aset_id = aset->aset_id;
        pe->key_type = p_ctc_entry->key_type;
        pe->entry_id = p_ctc_entry->entry_id;
        pe->key_index = 0XFFFFFF;   /*0xFFFFFF means key_index is not sure*/
        pe->hash_field_sel_id = p_ctc_entry->hash_field_sel_id;
        pe->action_type = action_type;
        CTC_ERROR_GOTO(_sys_usw_acl_add_hash_entry(lchip, pe), ret, free_pe);
        if(SYS_ACL_FK_IS_FLEX_HASH0(fk))
        {
            uint8 loop;
            ctc_acl_kset_t* p_kset_base = &p_usw_acl_master[lchip]->support_kset[CTC_BOTH_DIRECTION + ((sys_acl_flex_hash_t*)fk)->origin_key_type -CTC_ACL_KEY_HASH_MAC];
            sys_acl_kset_t* p_kset = &((sys_acl_flex_hash_t*)fk)->kset;
            if(2 != ((sys_acl_flex_hash_t*)fk)->mode)
            {
                for (loop = 0; loop < CTC_B2W_SIZE(CTC_FIELD_KEY_NUM); loop++)
                {
                    pe->ua->buffer.kset.w[loop] = p_kset->w[loop]&(~p_kset_base->w[loop]);
                }
            }
            else
            {
               sal_memcpy(&pe->ua->buffer.kset, p_kset, sizeof(ctc_acl_kset_t));
            }
        }
    }

    /*tcam entry*/
    else
    {
        sys_acl_entry_t* pe_tcam = NULL;
        uint8 temp_ad_type = SYS_ACL_AD_TYPE_NONE;

        if (SYS_ACL_IS_RSV_GROUP(pg_lkup->group_id)) /* tcam entry only in tcam group */
        {
            ret = CTC_E_INVALID_CONFIG;
            goto free_aset;
        }

        /*if (aset_level != SYS_ACL_ASET_LEVEL_ACTION)
        {
            CTC_ERROR_GOTO(_sys_usw_acl_check_aset(lchip, pg_lkup->group_info.dir, utype, aset), ret, free_aset);
            if(p_ctc_entry->aset && CTC_BMP_ISSET((uint32*)aset, CTC_ACL_FIELD_ACTION_XDATA))
            {
                CTC_ERROR_GOTO(_sys_usw_acl_check_xdata(lchip, pg_lkup, p_ctc_entry->aset->profile_id, aset, 0), ret, free_aset);
            }
            _sys_usw_acl_judge_ad_type_by_aset(lchip, pg_lkup->group_info.dir, aset, &temp_ad_type);
        }*/

        pe = mem_malloc(MEM_ACL_MODULE, sizeof(sys_acl_entry_t));
        if (!pe)
        {
            ret = CTC_E_NO_MEMORY;
            goto free_aset;
        }
        sal_memset(pe, 0, sizeof(sys_acl_entry_t));
        pe_tcam = ACL_SHARE_PTR(pe,sys_acl_entry_t);

        if((CTC_ACL_KEY_COPP != p_ctc_entry->key_type) && (CTC_ACL_KEY_COPP_EXT != p_ctc_entry->key_type))
        {
            pg_lkup->group_info.bitmap_status = ACL_BITMAP_STATUS_16;
        }

        pe_tcam->ua = (void*)buffer;
        pe_tcam->group = pg_lkup;
        pe_tcam->ua->buffer.fk = fk;
        pe_tcam->ua->buffer.aset = aset;
        pe_tcam->aset_id = aset->aset_id;
        pe_tcam->ad_type = temp_ad_type;
        pe_tcam->key_type = p_ctc_entry->key_type;
        pe_tcam->fpae.entry_id = p_ctc_entry->entry_id;
        pe_tcam->fpae.offset_a = CTC_MAX_UINT32_VALUE;   /*0xFFFFFFFF means key_index is not sure*/
        pe_tcam->fpae.priority = !p_ctc_entry->priority_valid ? FPA_PRIORITY_DEFAULT : p_ctc_entry->priority;
        pe_tcam->u1_type = aset->u1_type;
        pe_tcam->u2_type = aset->u2_type;
        pe_tcam->u3_type = aset->u3_type;
        pe_tcam->u4_type = aset->u4_type;
        pe_tcam->u5_type = aset->u5_type;
        pe_tcam->action_type = action_type;
        CTC_ERROR_GOTO(_sys_usw_acl_add_tcam_entry(lchip, p_ctc_entry->priority_valid, pe_tcam), ret, free_pe);
    }

    return CTC_E_NONE;

free_pe:
    mem_free(pe);
free_aset:
    _sys_usw_acl_remove_aset(lchip, aset->aset_id);
free_buffer:
    mem_free(buffer);
    return ret;
}



int32
_sys_usw_acl_remove_entry(uint8 lchip, uint32 entry_id)
{
    sys_acl_group_t* pg = NULL;
    sys_acl_entry_t* pe = NULL;
    sys_acl_block_t* pb = NULL;
    sys_acl_flex_key_t* fk = NULL;
    ctc_acl_field_action_t action_field;


    /* check raw entry */
    _sys_usw_acl_get_nodes_by_eid(lchip, entry_id, &pe, &pg, &pb);
    if((!pe) || (!pg))
    {
        CTC_ERROR_RETURN(CTC_E_NOT_EXIST);
    }
    if (ACL_ENTRY_IS_INSTALLED(pe))
    {
        CTC_ERROR_RETURN(CTC_E_INVALID_CONFIG);
    }

    if (!ACL_ENTRY_IS_TCAM(pe))
    {
        return _sys_usw_acl_remove_entry_hash(lchip, (sys_acl_hash_entry_t*)pe);
    }

    if (pe->ua->buffer.fk && SYS_ACL_GROUP_IS_PRESEL(pg))
    {
        fk = pe->ua->buffer.fk;
        fk->entry_count[pg->group_info.block_id]--;
    }
    else if (pe->ua->buffer.fk)
    {
        ACL_SHARE_PTR(pe->ua->buffer.fk, sys_acl_fixed_key_t)->entry_count--;
    }
    /*reset action to default ,free resource*/
    sal_memset(&action_field,0,sizeof(action_field));
    action_field.type = CTC_ACL_FIELD_ACTION_CANCEL_ALL;

    if (DRV_FROM_TMM(lchip) && CTC_EGRESS == pe->group->group_info.dir)
    {
            CTC_ERROR_RETURN(MCHIP_ACL(lchip)->add_egs_action_field(lchip, &action_field, pe, 1));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_usw_acl_add_dsacl_field(lchip, &action_field, pe,(CTC_ACL_KEY_INTERFACE == pe->key_type), 1));
    }
    CTC_ERROR_RETURN(_sys_usw_acl_remove_tcam_entry(lchip, pe, pg, pb));


    if (MCHIP_ACL(lchip)->compress_link_block &&
        (CTC_INGRESS == pg->group_info.dir || DRV_FROM_AT(lchip)))
    {
        CTC_ERROR_RETURN(MCHIP_ACL(lchip)->compress_link_block(lchip, pb, fk));
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_TCAM_ENTRY, 1);
    return CTC_E_NONE;
}

int32
_sys_usw_acl_remove_all_entry(uint8 lchip, uint32 group_id)
{
    sys_acl_group_t* pg      = NULL;
    ctc_list_pointer_node_t* pe      = NULL;
    ctc_list_pointer_node_t* pe_next = NULL;
    uint32           eid     = 0;

    /* get group node */
    _sys_usw_acl_get_group_by_gid(lchip, group_id, &pg);
    SYS_ACL_CHECK_GROUP_UNEXIST(pg);

    /* check if all uninstalled */
    CTC_LIST_POINTER_LOOP(pe, &(pg->entry_list))
    {
        if (ACL_ENTRY_IS_INSTALLED((sys_acl_entry_t*)pe))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [Acl] Entry installed \n");
            return CTC_E_INVALID_CONFIG;
        }
    }

    CTC_LIST_POINTER_LOOP_DEL(pe, pe_next ,&(pg->entry_list))
    {
        eid = ((sys_acl_entry_t *) pe)->fpae.entry_id;
        /* no stop to keep consitent */
        _sys_usw_acl_remove_entry(lchip, eid);
        sys_usw_com_remove_entry_hash_by_entry_id(lchip, p_usw_acl_master[lchip]->entry_hash_db[SYS_COM_ENTRY_HASH_ACL_ENTRY], eid);
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_check_hash_sel_field_union(uint8 lchip, uint8 hash_type, uint8 field_sel_id, ctc_field_key_t* sel_field)
{
    uint8 l3_type=CTC_PARSER_L3_TYPE_NONE;
    sys_hash_sel_field_union_t*  p_sel_field_union;
    uint8 l2_l3_key = (hash_type == SYS_ACL_HASH_KEY_TYPE_L2_L3);
    uint8 l3_key = (hash_type == SYS_ACL_HASH_KEY_TYPE_IPV4);
    uint8 ipv6_key = (hash_type == SYS_ACL_HASH_KEY_TYPE_IPV6);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!sel_field->data)
    {
        return CTC_E_NONE;
    }
    p_sel_field_union = &(p_usw_acl_master[lchip]->hash_sel_key_union_filed[hash_type][field_sel_id]);

    switch(sel_field->type)
    {
    case CTC_FIELD_KEY_PORT:
        if (p_sel_field_union->key_port_type == 2)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to metadata field\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_METADATA:
        if (p_sel_field_union->key_port_type == 1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to port field\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IP_FRAG:                  /**< [D2] IP Fragment Information. */
    case CTC_FIELD_KEY_IP_HDR_ERROR:             /**< [D2] Ip Header Error. */
    case CTC_FIELD_KEY_IP_OPTIONS:               /**< [D2] Ip Options. */
    case CTC_FIELD_KEY_IP_TTL:                   /**< [D2] Ttl. */
        if (l3_key)
        {
            if(sel_field->type == CTC_FIELD_KEY_IP_TTL)
            {
                if(p_sel_field_union->l3_key_u1_type == 2 || p_sel_field_union->l3_key_u1_type == 3  ||
                  (p_sel_field_union->l3_key_u1_bmp != 0 && (p_sel_field_union->l3_key_u1_bmp & 0x09) == 0) )
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key u1_type:%d, u1_bmp:0x%x.\n", p_sel_field_union->l3_key_u1_type, p_sel_field_union->l3_key_u1_bmp);
                    return CTC_E_INVALID_PARAM;
                }
            }
            else if(p_sel_field_union->l3_key_u1_type == 3 || (p_sel_field_union->l3_key_u1_bmp != 0 && (p_sel_field_union->l3_key_u1_bmp & 0x0b) == 0))
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key u1_type:%d, u1_bmp:0x%x.\n", p_sel_field_union->l3_key_u1_type, p_sel_field_union->l3_key_u1_bmp);
                return CTC_E_INVALID_PARAM;
            }
        }
        else if(ipv6_key)
        {
            if(p_sel_field_union->ipv6_key_ip_mode == 1 )
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "ipv6 key ipv6_key_ip_mode:%d\n", p_sel_field_union->ipv6_key_ip_mode);
                return CTC_E_INVALID_PARAM;
            }
        }
        else if (l2_l3_key
            && (p_sel_field_union->l2_l3_key_ul3_type == 2))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to mpls field\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IP_SA:                    /**< [D2] Source IPv4 Address. */
    case CTC_FIELD_KEY_IP_DA:                    /**< [D2] Destination IPv4 Address. */
    case CTC_FIELD_KEY_IPV6_SA:                  /**< [D2] Source IPv6 Address. */
    case CTC_FIELD_KEY_IPV6_DA:                  /**< [D2] Destination IPv6 Address. */
    case CTC_FIELD_KEY_IP_DSCP:                  /**< [D2] DSCP. */
    case CTC_FIELD_KEY_IP_PRECEDENCE:            /**< [D2] Precedence. */
    case CTC_FIELD_KEY_IP_ECN:                   /**< [D2] Ecn. */
        if (ipv6_key
            && (p_sel_field_union->ipv6_key_ip_mode == 1 )
            && !((CTC_FIELD_KEY_IPV6_SA == sel_field->type) || (CTC_FIELD_KEY_IPV6_DA == sel_field->type)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "ipv6 key ipv6_key_ip_mode:%d\n", p_sel_field_union->ipv6_key_ip_mode);
            return CTC_E_INVALID_PARAM;
        }
        if (l2_l3_key
            && (p_sel_field_union->l2_l3_key_ul3_type == 2))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to mpls field\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IPV6_FLOW_LABEL:          /**< [D2] Ipv6 Flow label*/
        if (ipv6_key
            && (p_sel_field_union->ipv6_key_ip_mode == 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "ipv6 key ipv6_key_ip_mode:%d\n", p_sel_field_union->ipv6_key_ip_mode);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IP_PROTOCOL:
        /*only u1.g4 support IP_PROTOCOL*/
        if (l3_key
            && (p_sel_field_union->l3_key_u1_type != 0)
            && (p_sel_field_union->l3_key_u1_type != 4 || (p_sel_field_union->l3_key_u1_bmp != 0 && (p_sel_field_union->l3_key_u1_bmp & 0x08) == 0)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key u1_type:%d, u1_bmp:0x%x.\n", p_sel_field_union->l3_key_u1_type, p_sel_field_union->l3_key_u1_bmp);
            return CTC_E_INVALID_PARAM;
        }
        /*only u1.g2 support IP_PROTOCOL*/
        if (ipv6_key && p_sel_field_union->ipv6_key_ip_mode == 1)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "ipv6 key ipv6_key_ip_mode:%d\n", p_sel_field_union->ipv6_key_ip_mode);
            return CTC_E_INVALID_PARAM;
        }

        break;
    case CTC_FIELD_KEY_TCP_ECN:                  /**< [D2] TCP Ecn. */
    case CTC_FIELD_KEY_TCP_FLAGS:                /**< [D2] TCP Flags (ctc_acl_tcp_flag_flag_t). */
        if (l3_key
            && (p_sel_field_union->l3_key_u1_type == 2 || p_sel_field_union->l3_key_u1_type == 4
                || (p_sel_field_union->l3_key_u1_bmp != 0 && (p_sel_field_union->l3_key_u1_bmp & 0x08) == 0)) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key u1_type:%d, u1_bmp:0x%x.\n", p_sel_field_union->l3_key_u1_type, p_sel_field_union->l3_key_u1_bmp);
            return CTC_E_INVALID_PARAM;
        }
        if (ipv6_key && (p_sel_field_union->ipv6_key_ip_mode == 1 ))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key u1_type:%d\n", p_sel_field_union->l3_key_u1_type);
            return CTC_E_INVALID_PARAM;
        }
        if (l2_l3_key && (p_sel_field_union->l2_l3_key_ul3_type == 2))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to mpls field\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_L4_DST_PORT:     /* l4_port_field; 3:l4 port */    /**< [D2] Layer 4 Dest Port. */
    case CTC_FIELD_KEY_L4_SRC_PORT:     /* l4_port_field; 3:l4 port */    /**< [D2] Layer 4 Src Port. */
        if ((l3_key || ipv6_key || l2_l3_key)
            && (p_sel_field_union->l4_port_field == 1 || p_sel_field_union->l4_port_field == 2
            || p_sel_field_union->l4_port_field == 4  || p_sel_field_union->l4_port_field == 5))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l4_port_field:%d\n", p_sel_field_union->l4_port_field);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IP_PKT_LEN_RANGE:         /**< [D2] Ip Packet Length Range. */
    case CTC_FIELD_KEY_L4_SRC_PORT_RANGE:        /**< [D2] Layer 4 Src Port Range;
        data: min: mask: max. */
    case CTC_FIELD_KEY_L4_DST_PORT_RANGE:        /**< [D2] Layer 4 Dest Port Range;
        data: min: mask: max. */
        if (l3_key
            && (p_sel_field_union->l3_key_u1_type == 1 || p_sel_field_union->l3_key_u1_type == 2 || p_sel_field_union->l3_key_u1_type == 4
                || (p_sel_field_union->l3_key_u1_bmp != 0 && (p_sel_field_union->l3_key_u1_bmp & 0x04) == 0) ) )
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key u1_type:%d, u1_bmp:0x%x.\n", p_sel_field_union->l3_key_u1_type, p_sel_field_union->l3_key_u1_bmp);
            return CTC_E_INVALID_PARAM;
        }
        if (ipv6_key
            && (p_sel_field_union->ipv6_key_ip_mode == 1))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " ipv6_key The filed is used to full ip\n");
            return CTC_E_INVALID_PARAM;
        }
        if (l2_l3_key
            && (p_sel_field_union->l2_l3_key_ul3_type == 2))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to mpls field\n");
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_GRE_KEY:   /* l4_port_field; 1:gre/nvgre */
        if (((l3_key || ipv6_key || l2_l3_key)
            &&(p_sel_field_union->l4_port_field ==2 || p_sel_field_union->l4_port_field ==3
               ||p_sel_field_union->l4_port_field ==4 || p_sel_field_union->l4_port_field ==5))
            ||((l3_key || ipv6_key || l2_l3_key) &&(p_sel_field_union->l4_port_field ==1)
            &&((p_sel_field_union->l4_port_field_bmp & 0x02) !=0)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to other field :l4_port_field:%d\n", p_sel_field_union->l4_port_field);
            return CTC_E_INVALID_PARAM;
        }
        break;

    case CTC_FIELD_KEY_NVGRE_KEY: /* l4_port_field; 1:gre/nvgre */
        if (((l3_key || ipv6_key || l2_l3_key)
            &&(p_sel_field_union->l4_port_field ==2 || p_sel_field_union->l4_port_field ==3
               ||p_sel_field_union->l4_port_field ==4 || p_sel_field_union->l4_port_field ==5))
            ||((l3_key || ipv6_key || l2_l3_key) &&(p_sel_field_union->l4_port_field ==1)
            &&((p_sel_field_union->l4_port_field_bmp &0x01) !=0)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to other field :l4_port_field:%d\n", p_sel_field_union->l4_port_field);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_ICMP_CODE: /* l4_port_field; 4:icmp */
    case CTC_FIELD_KEY_ICMP_TYPE: /* l4_port_field; 4:icmp */
        if ((l3_key || ipv6_key || l2_l3_key)
            &&(p_sel_field_union->l4_port_field ==1 || p_sel_field_union->l4_port_field ==2
            ||p_sel_field_union->l4_port_field ==3|| p_sel_field_union->l4_port_field ==5))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to other field :l4_port_field:%d\n", p_sel_field_union->l4_port_field);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_IGMP_TYPE: /* 5:igmp */
        if (ipv6_key              /* ASIC:hash key only ipv6 support igmp */
            &&(p_sel_field_union->l4_port_field ==1 || p_sel_field_union->l4_port_field ==2
            ||p_sel_field_union->l4_port_field ==3 || p_sel_field_union->l4_port_field ==4))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to other field :l4_port_field:%d\n", p_sel_field_union->l4_port_field);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_MPLS_LABEL0:              /**< [D2] Label Field of the MPLS Label 0. */
    case CTC_FIELD_KEY_MPLS_EXP0:                /**< [D2] Exp Field of the MPLS Label 0.*/
    case CTC_FIELD_KEY_MPLS_SBIT0:               /**< [D2] S-bit Field of the MPLS Label 0.*/
    case CTC_FIELD_KEY_MPLS_TTL0:                /**< [D2] Ttl Field of the MPLS Label 0.*/
    case CTC_FIELD_KEY_MPLS_LABEL1:              /**< [D2] Label Field of the MPLS Label 1. */
    case CTC_FIELD_KEY_MPLS_EXP1:                /**< [D2] Exp Field of the MPLS Label 1.*/
    case CTC_FIELD_KEY_MPLS_SBIT1:               /**< [D2] S-bit Field of the MPLS Label 1.*/
    case CTC_FIELD_KEY_MPLS_TTL1:                /**< [D2] Ttl Field of the MPLS Label 1.*/
    case CTC_FIELD_KEY_MPLS_LABEL2:              /**< [D2] Label Field of the MPLS Label 2. */
    case CTC_FIELD_KEY_MPLS_EXP2:                /**< [D2] Exp Field of the MPLS Label 2.*/
    case CTC_FIELD_KEY_MPLS_SBIT2:               /**< [D2] S-bit Field of the MPLS Label 2.*/
    case CTC_FIELD_KEY_MPLS_TTL2:                /**< [D2] Ttl Field of the MPLS Label 2.*/
        if (l2_l3_key && (p_sel_field_union->l2_l3_key_ul3_type == 1 || p_sel_field_union->l2_l3_key_ul3_type == 3))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to Ip field or Unknown_etherType:%d\n",p_sel_field_union->l2_l3_key_ul3_type );
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_VRFID:
    case CTC_FIELD_KEY_IS_ROUTER_MAC:
        if (l3_key
            && (p_sel_field_union->l3_key_u1_type ==1 ||p_sel_field_union->l3_key_u1_type ==3 || p_sel_field_union->l3_key_u1_type ==4
                || (p_sel_field_union->l3_key_u1_bmp != 0 && (p_sel_field_union->l3_key_u1_bmp & 0x02) == 0) ))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l3 key u1_type:%d, u1_bmp:0x%x.\n", p_sel_field_union->l3_key_u1_type, p_sel_field_union->l3_key_u1_bmp);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_VN_ID:  /* l4_port_field; 2:vxlan  */
        if ((l3_key || ipv6_key || l2_l3_key)
            && (p_sel_field_union->l4_port_field == 1 || p_sel_field_union->l4_port_field == 3
            || p_sel_field_union->l4_port_field == 4  || p_sel_field_union->l4_port_field == 5))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "l4_port_field:%d\n", p_sel_field_union->l4_port_field);
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_FIELD_KEY_ETHER_TYPE:
        if (l2_l3_key && (p_sel_field_union->l2_l3_key_ul3_type == 1 || p_sel_field_union->l2_l3_key_ul3_type == 2 ))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "The filed is used to Ip field or Mpls fields:%d\n",p_sel_field_union->l2_l3_key_ul3_type);
            return CTC_E_INVALID_PARAM;
        }
        if (l2_l3_key && ((CTC_PARSER_L3_TYPE_IPV4 ==l3_type) || (CTC_PARSER_L3_TYPE_MPLS ==l3_type) || (CTC_PARSER_L3_TYPE_MPLS_MCAST ==l3_type)))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Key filed:%s (EthType:0x%x) in l2_l3_key must be unknownPktEther .\n (l3_type:%d)n", "CTC_FIELD_KEY_ETHER_TYPE", sel_field->data, l3_type);
        }
        break;
    default :
        break;
    }

    return CTC_E_NONE;

}

int32
_sys_usw_acl_set_hash_sel_field_union(uint8 lchip, uint8 hash_type, uint8 field_sel_id, ctc_field_key_t* sel_field, uint8 is_add)
{
    sys_hash_sel_field_union_t*  p_sel_field_union;
    uint8 l2_l3_key = (hash_type == SYS_ACL_HASH_KEY_TYPE_L2_L3);
    uint8 l3_key = (hash_type == SYS_ACL_HASH_KEY_TYPE_IPV4);
    uint8 ipv6_key = (hash_type == SYS_ACL_HASH_KEY_TYPE_IPV6);
    uint8 i = 0;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    p_sel_field_union = &(p_usw_acl_master[lchip]->hash_sel_key_union_filed[hash_type][field_sel_id]);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_MASTER, 1);
    switch(sel_field->type)
    {
    case CTC_FIELD_KEY_PORT:
        p_sel_field_union->key_port_type = is_add ? 1 :0;
        break;
    case CTC_FIELD_KEY_METADATA:
        p_sel_field_union->key_port_type = is_add ? 2 :0;
        break;
    case CTC_FIELD_KEY_IP_FRAG:                  /**< [D2] IP Fragment Information. */
    case CTC_FIELD_KEY_IP_HDR_ERROR:             /**< [D2] Ip Header Error. */
    case CTC_FIELD_KEY_IP_OPTIONS:               /**< [D2] Ip Options. */
    case CTC_FIELD_KEY_IP_TTL:                   /**< [D2] Ttl. */
        if(l3_key)
        {
            if(sel_field->type == CTC_FIELD_KEY_IP_TTL)
            {
                p_sel_field_union->l3_key_u1_bmp = p_sel_field_union->l3_key_u1_bmp ? (p_sel_field_union->l3_key_u1_bmp & 0x09) : 0x09;
                if(p_sel_field_union->l3_key_u1_bmp == 1 )
                {
                    p_sel_field_union->l3_key_u1_type = 1;
                }
                else if(p_sel_field_union->l3_key_u1_bmp == 8)
                {
                    p_sel_field_union->l3_key_u1_type = 4;
                }
            }
            else
            {
                p_sel_field_union->l3_key_u1_bmp = p_sel_field_union->l3_key_u1_bmp ? (p_sel_field_union->l3_key_u1_bmp & 0x0b) : 0x0b;
                for(i = 1; i < 5 ; i++)
                {
                    if(p_sel_field_union->l3_key_u1_bmp == (1 << (i-1)))
                    {
                        p_sel_field_union->l3_key_u1_type = i;
                    }
                }
            }
        }
        else if(ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 2;
        }
        else if (l2_l3_key)
        {
            p_sel_field_union->l2_l3_key_ul3_type = is_add ? 1 :0;
        }
        break;

    case CTC_FIELD_KEY_IP_DSCP:                  /**< [D2] DSCP. */
    case CTC_FIELD_KEY_IP_ECN:                   /**< [D2] Ecn. */
        if(ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 2;
        }
        else if (l2_l3_key)
        {
            p_sel_field_union->l2_l3_key_ul3_type = is_add ? 1 :0;
        }
        break;

    case CTC_FIELD_KEY_IP_SA:                    /**< [D2] Source IPv4 Address. */
    case CTC_FIELD_KEY_IP_DA:                    /**< [D2] Destination IPv4 Address. */
    case CTC_FIELD_KEY_IP_PRECEDENCE:            /**< [D2] Precedence. */
        if (l2_l3_key)
        {
            p_sel_field_union->l2_l3_key_ul3_type = is_add ? 1 :0;
        }
        break;

    /* for 3:l4 port;   bit2:CTC_FIELD_KEY_L4_DST_PORT; bit3:CTC_FIELD_KEY_L4_SRC_PORT; (can exist at the same time)*/
    case CTC_FIELD_KEY_L4_DST_PORT:              /**< [D2] Layer 4 Dest Port. */
        if (l3_key || ipv6_key || l2_l3_key)
        {
            if(is_add)
            {
                p_sel_field_union->l4_port_field_bmp |= 0x04;
                p_sel_field_union->l4_port_field = 3;
            }
            else
            {
                p_sel_field_union->l4_port_field_bmp &= ~0x04;
                p_sel_field_union->l4_port_field = ( (p_sel_field_union->l4_port_field_bmp & 0x0C) == 0) ? 0 : p_sel_field_union->l4_port_field;
            }
        }
        break;
    /* for 3:l4 port;   bit2:CTC_FIELD_KEY_L4_DST_PORT; bit3:CTC_FIELD_KEY_L4_SRC_PORT; (can exist at the same time)*/
    case CTC_FIELD_KEY_L4_SRC_PORT:              /**< [D2] Layer 4 Src Port. */
        if (l3_key || ipv6_key || l2_l3_key)
        {
            if(is_add)
            {
                p_sel_field_union->l4_port_field_bmp |= 0x08;
                p_sel_field_union->l4_port_field = 3;
            }
            else
            {
                p_sel_field_union->l4_port_field_bmp &= ~0x08;
                p_sel_field_union->l4_port_field = ( (p_sel_field_union->l4_port_field_bmp & 0x0C) == 0) ? 0 : p_sel_field_union->l4_port_field;
            }
        }
        break;
    case CTC_FIELD_KEY_IP_PKT_LEN_RANGE:         /**< [D2] Ip Packet Length Range. */
    case CTC_FIELD_KEY_L4_SRC_PORT_RANGE:        /**< [D2] Layer 4 Src Port Range;
        data: min: mask: max. */
    case CTC_FIELD_KEY_L4_DST_PORT_RANGE:        /**< [D2] Layer 4 Dest Port Range;
        data: min: mask: max. */
        if (l3_key)
        {
            p_sel_field_union->l3_key_u1_bmp = 0x04;
            p_sel_field_union->l3_key_u1_type = 3;
        }
        if (ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 2;
        }
        if (l2_l3_key)
        {
            p_sel_field_union->l2_l3_key_ul3_type = is_add ? 1 :0;
        }
        break;
    case CTC_FIELD_KEY_TCP_ECN:                  /**< [D2] TCP Ecn. */
    case CTC_FIELD_KEY_TCP_FLAGS:                /**< [D2] TCP Flags (ctc_acl_tcp_flag_flag_t). */
        if (l2_l3_key )
        {
            p_sel_field_union->l2_l3_key_ul3_type = is_add ? 1 :0;
        }
        else if(ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 2;
        }
        else
        {
            p_sel_field_union->l3_key_u1_bmp = p_sel_field_union->l3_key_u1_bmp ? (p_sel_field_union->l3_key_u1_bmp & 0x05) : 0x05;
            if(p_sel_field_union->l3_key_u1_bmp == 0x01)
            {
                p_sel_field_union->l3_key_u1_type = 1;
            }
            else if (p_sel_field_union->l3_key_u1_bmp == 0x04)
            {
                p_sel_field_union->l3_key_u1_type = 3;
            }
        }
        break;
    case CTC_FIELD_KEY_GRE_KEY:  /*for 1:gre/nvgre; bit0:CTC_FIELD_KEY_GRE_KEY;     bit1:CTC_FIELD_KEY_NVGRE_KEY;   (can't exist at the same time)*/
        if (l3_key || ipv6_key || l2_l3_key)
        {
            if(is_add)
            {
                p_sel_field_union->l4_port_field_bmp |= 0x01;
                p_sel_field_union->l4_port_field = 1;
            }
            else
            {
                p_sel_field_union->l4_port_field_bmp &= ~0x01;
                p_sel_field_union->l4_port_field = ( (p_sel_field_union->l4_port_field_bmp & 0x03) == 0) ? 0 : p_sel_field_union->l4_port_field;
            }
        }
        break;
    case CTC_FIELD_KEY_NVGRE_KEY: /*for 1:gre/nvgre; bit0:CTC_FIELD_KEY_GRE_KEY;     bit1:CTC_FIELD_KEY_NVGRE_KEY;   (can't exist at the same time)*/
        if (l3_key || ipv6_key || l2_l3_key)
        {
            if(is_add)
            {
                p_sel_field_union->l4_port_field_bmp |= 0x02;
                p_sel_field_union->l4_port_field = 1;
            }
            else
            {
                p_sel_field_union->l4_port_field_bmp &= ~0x02;
                p_sel_field_union->l4_port_field = ( (p_sel_field_union->l4_port_field_bmp & 0x03) == 0) ? 0 : p_sel_field_union->l4_port_field;
            }
        }
        break;

    case CTC_FIELD_KEY_ICMP_TYPE:  /*for 4:icmp; bit4:CTC_FIELD_KEY_ICMP_CODE; bit5:CTC_FIELD_KEY_ICMP_TYPE; (can exist at the same time)*/
        if (l3_key || ipv6_key || l2_l3_key)
        {
            if(is_add)
            {
                p_sel_field_union->l4_port_field_bmp |= 0x20;
                p_sel_field_union->l4_port_field = 4;
            }
            else
            {
                p_sel_field_union->l4_port_field_bmp &= ~0x20;
                p_sel_field_union->l4_port_field = ( (p_sel_field_union->l4_port_field_bmp & 0x30) == 0) ? 0 : p_sel_field_union->l4_port_field;
            }
        }
        break;
    case CTC_FIELD_KEY_ICMP_CODE:   /*for 4:icmp; bit4:CTC_FIELD_KEY_ICMP_CODE; bit5:CTC_FIELD_KEY_ICMP_TYPE; (can exist at the same time)*/
        if (l3_key || ipv6_key || l2_l3_key)
        {
            if(is_add)
            {
                p_sel_field_union->l4_port_field_bmp |= 0x10;
                p_sel_field_union->l4_port_field = 4;
            }
            else
            {
                p_sel_field_union->l4_port_field_bmp &= ~0x10;
                p_sel_field_union->l4_port_field = ( (p_sel_field_union->l4_port_field_bmp & 0x30) == 0) ? 0 : p_sel_field_union->l4_port_field;
            }
        }
        break;

    case CTC_FIELD_KEY_IGMP_TYPE:    /*for 5:igmp;      CTC_FIELD_KEY_IGMP_TYPE (only one field, no need l4_port_field_bmp)*/
        p_sel_field_union->l4_port_field = is_add ? 5:0;
        break;
    case CTC_FIELD_KEY_MPLS_LABEL0:              /**< [D2] Label Field of the MPLS Label 0. */
    case CTC_FIELD_KEY_MPLS_EXP0:                /**< [D2] Exp Field of the MPLS Label 0.*/
    case CTC_FIELD_KEY_MPLS_SBIT0:               /**< [D2] S-bit Field of the MPLS Label 0.*/
    case CTC_FIELD_KEY_MPLS_TTL0:                /**< [D2] Ttl Field of the MPLS Label 0.*/
    case CTC_FIELD_KEY_MPLS_LABEL1:              /**< [D2] Label Field of the MPLS Label 1. */
    case CTC_FIELD_KEY_MPLS_EXP1:                /**< [D2] Exp Field of the MPLS Label 1.*/
    case CTC_FIELD_KEY_MPLS_SBIT1:               /**< [D2] S-bit Field of the MPLS Label 1.*/
    case CTC_FIELD_KEY_MPLS_TTL1:                /**< [D2] Ttl Field of the MPLS Label 1.*/
    case CTC_FIELD_KEY_MPLS_LABEL2:              /**< [D2] Label Field of the MPLS Label 2. */
    case CTC_FIELD_KEY_MPLS_EXP2:                /**< [D2] Exp Field of the MPLS Label 2.*/
    case CTC_FIELD_KEY_MPLS_SBIT2:               /**< [D2] S-bit Field of the MPLS Label 2.*/
    case CTC_FIELD_KEY_MPLS_TTL2:                /**< [D2] Ttl Field of the MPLS Label 2.*/
        if (l2_l3_key)
        {
            p_sel_field_union->l2_l3_key_ul3_type = is_add ? 2 :0;
        }
        break;
    case CTC_FIELD_KEY_ETHER_TYPE:
        if (l2_l3_key)
        {
            p_sel_field_union->l2_l3_key_ul3_type = is_add ? 3:0;
        }
        break;
    case CTC_FIELD_KEY_VN_ID:   /*for 2:vxlan;     CTC_FIELD_KEY_VN_ID     (only one field, no need l4_port_field_bmp)*/
        if (l3_key || ipv6_key || l2_l3_key)
        {
            p_sel_field_union->l4_port_field = is_add ? 2 :0;
        }
        break;
   case CTC_FIELD_KEY_VRFID:
   case CTC_FIELD_KEY_IS_ROUTER_MAC:
        if (l3_key)
        {
            p_sel_field_union->l3_key_u1_bmp = 0x02;
            p_sel_field_union->l3_key_u1_type = 2;
        }
        if(CTC_FIELD_KEY_VRFID == sel_field->type && ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 2;
        }
        break;
    case CTC_FIELD_KEY_IP_PROTOCOL:
        /*only u1.g4 support IP_PROTOCOL*/
        if (l3_key)
        {
            p_sel_field_union->l3_key_u1_bmp = 0x08;
            p_sel_field_union->l3_key_u1_type = 4;
        }
        else if(ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 2;
        }
        break;
    case CTC_FIELD_KEY_IPV6_FLOW_LABEL:
        if(ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 2;
        }
        break;
    default :
        break;
    }

    if(!is_add)
    {
        if(l3_key)
        {
            p_sel_field_union->l3_key_u1_bmp = 0;
            p_sel_field_union->l3_key_u1_type = 0;
        }
        else if(ipv6_key)
        {
            p_sel_field_union->ipv6_key_ip_mode = 0;
        }
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_MASTER, 1);
    return CTC_E_NONE;
}

int32
_sys_usw_acl_free_entry_node_data(void* node_data, void* user_data)
{
    uint32 free_entry_hash = 0;
    sys_acl_entry_t* pe = NULL;

    if (user_data)
    {
        free_entry_hash = *(uint32*)user_data;
        if (1 == free_entry_hash)
        {
            pe = (sys_acl_entry_t*)node_data;
            if (pe->ua && pe->ua_type == 0)     /*buffer*/
            {
                if(pe->ua->buffer.pa)
                {
                    mem_free(pe->ua->buffer.pa);
                }
                mem_free(pe->ua);
            }
            else if(pe->ua && (1 == pe->ua_type) && (ACL_ENTRY_IS_TCAM(pe) || 
                (SYS_ACL_KEY_IS_FLEX(pe->key_type) && !SYS_ACL_KEY_IS_FLEX_HASH0(pe->action_type, pe->key_type, pe->group->group_info.block_id))))      /*action_data*/
            {
                mem_free(pe->ua);
            }
            /*if(NULL != pe->aset && pe->aset_level != SYS_ACL_ASET_LEVEL_GROUP)
            {
                mem_free(pe->aset)
            }*/
        }
    }

    mem_free(node_data);

    return CTC_E_NONE;
}

int32
_sys_usw_acl_free_group_node_data(void* node_data, void* user_data)
{
    if (node_data)
    {
        /*if(NULL != pg->aset)
        {
            mem_free(pg->aset)
        }*/

        mem_free(node_data);
    }

    return CTC_E_NONE;
}
#if 0
int32
_sys_usw_acl_set_key_union_type(uint8 lchip, sys_acl_entry_t* pe, uint16 key_type, uint8 is_add)
{
    switch(key_type)
    {
    case CTC_FIELD_KEY_L3_TYPE:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_L3_TYPE, is_add);
        break;
    case CTC_FIELD_KEY_L4_TYPE:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_L4_TYPE, is_add);
        break;
    case CTC_FIELD_KEY_IS_Y1731_OAM:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_Y1731, is_add);
        break;
    case CTC_FIELD_KEY_CLASS_ID:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_CLASS_ID, is_add);
        break;
    case CTC_FIELD_KEY_UDF:     /*0:udf_id  1:udf_ad_id;  for show*/
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_UDF, 0);
        break;
    case CTC_FIELD_KEY_UDF_AD_ID:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_UDF, is_add);
        break;
    case CTC_FIELD_KEY_SUDF:    /*0:sudf_id 1:sudf_ad_id; for show*/
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_SUDF, 0);
        break;
    case CTC_FIELD_KEY_SUDF_AD_ID:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_SUDF, is_add);
        break;
    case CTC_FIELD_KEY_NPM_IM_L_FLAG:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_NPM_IM_L_FLAG, is_add);
        break;
    case CTC_FIELD_KEY_NPM_IM_D_FLAG:
        SYS_ACL_SET_FLAG(pe->flag, SYS_ACL_ENTRY_FLAG_NPM_IM_D_FLAG, is_add);
        break;

    default:
        break;
    }

    return CTC_E_NONE;
}
#endif

#define _ACL_UDF_ENTRY_

int32
_sys_usw_acl_get_flow_udf_id_by_adindex_cb(void* bucket_data, void* user_data)
{
    uint16 flow_udf_adindex = 0;
    uint16 flow_udf_adindex_lkup = 0;
    sys_acl_udf_entry_t* p_sys_udf_entry = NULL;
    sys_acl_traverse_data_t* p_user_data = NULL;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = ((sys_acl_traverse_data_t*)user_data)->value0;
#endif
    p_sys_udf_entry = (sys_acl_udf_entry_t*)bucket_data;
    p_user_data = (sys_acl_traverse_data_t*)user_data;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    flow_udf_adindex = *(uint16*)(p_user_data->data0);
    flow_udf_adindex_lkup = p_sys_udf_entry->key_index;/* flow_udf means ad_index (515~1023,512,513,514 used in ipv6sr internal)*/

    if(flow_udf_adindex == flow_udf_adindex_lkup) /* 0 is not use because of ipv6sr */
    {
        *((uint32*)(p_user_data->data1)) = p_sys_udf_entry->udf_id;
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "flow udf entry ad index: %u\n", flow_udf_adindex_lkup);
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_get_flow_udf_id_by_adindex(uint8 lchip, uint16 ad_index, uint32* udf_id)
{
    uint32 udf_id_lkup = 0;
    sys_acl_traverse_data_t  user_data;

    sal_memset(&user_data, 0, sizeof(sys_acl_traverse_data_t));

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    user_data.data0 = (void*)&ad_index;
    user_data.data1 = (void*)&udf_id_lkup;
    user_data.value0 = lchip;
    CTC_ERROR_RETURN(ctc_hash_traverse(p_usw_acl_master[lchip]->udf_entry, _sys_usw_acl_get_flow_udf_id_by_adindex_cb, (void*) (&user_data)));
    *udf_id = *(uint32*)user_data.data1;

    return CTC_E_NONE;
}

int32
sys_usw_acl_get_flow_udf_id_by_adindex(uint8 lchip, uint16 ad_index, uint32* udf_id)
{
    int32 ret = CTC_E_NONE;
    CTC_PTR_VALID_CHECK(udf_id);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_USW_ACL_LOCK(lchip);
    ret = _sys_usw_acl_get_flow_udf_id_by_adindex(lchip, ad_index, udf_id);
    SYS_USW_ACL_UNLOCK(lchip);
    return ret;
}

int32
_sys_usw_acl_free_udf_entry_node_data(void* node_data, void* user_data)
{
    sys_acl_udf_entry_t* pe_udf = NULL;

    pe_udf = (sys_acl_udf_entry_t*)node_data;
    if (NULL != pe_udf->buffer)
    {
        mem_free(pe_udf->buffer);
    }

    mem_free(node_data);

    return CTC_E_NONE;
}

int32
_sys_usw_acl_get_udf_info(uint8 lchip,  uint32 udf_id, sys_acl_udf_entry_t **p_udf_entry)
{
    sys_acl_udf_entry_t sys_udf_entry;

    sys_udf_entry.udf_id = udf_id;

    *p_udf_entry = ctc_hash_lookup(p_usw_acl_master[lchip]->udf_entry, &sys_udf_entry);
    return CTC_E_NONE;
}

STATIC int32
_sys_acl_get_udf_by_ad_id_cb(void* entry, void* data)
{
    sys_acl_udf_entry_t* p_udf_entry;
    sys_traverse_t* p_user_data;
    p_user_data = (sys_traverse_t*)data;
    p_udf_entry = (sys_acl_udf_entry_t*)entry;
    if(p_udf_entry->udf_hit_index == p_user_data->value1)
    {
        p_user_data->data = p_udf_entry;
        return -1;
    }
    return 0;
}

int32 _sys_usw_acl_get_udf_entry_by_ad_id(uint8 lchip, uint32 udf_ad_id, sys_acl_udf_entry_t**pp_udf_entry)
{
    sys_traverse_t user_data;
    user_data.value1 = udf_ad_id;
    user_data.data = NULL;
    ctc_hash_traverse(p_usw_acl_master[lchip]->udf_entry, (hash_traversal_fn)_sys_acl_get_udf_by_ad_id_cb, &user_data);
    *pp_udf_entry = user_data.data;

    return 0;
}

int32
  _sys_usw_acl_udf_rebuild_buffer_from_hw(uint8 lchip,  sys_acl_udf_entry_t  *p_sys_udf_entry)
{
        ParserUdfCam_m udf_cam_data;
        ParserUdfCam_m udf_cam_mask;
        tbl_entry_t   tcam_key;
        void* p_ds = NULL;

        sal_memset(&udf_cam_data, 0, sizeof(ParserUdfCam_m));
        sal_memset(&udf_cam_mask, 0, sizeof(ParserUdfCam_m));
        tcam_key.data_entry = (uint32*)&udf_cam_data;
        tcam_key.mask_entry = (uint32*)&udf_cam_mask;

        p_ds = DRV_FROM_TMM(lchip)? (void*)&tcam_key: (void*)&udf_cam_data;
        CTC_ERROR_RETURN(sys_usw_parser_io_get_parser_udf_cam(lchip, p_ds, p_sys_udf_entry->key_index));
        if (NULL == p_sys_udf_entry->buffer)
        {
            MALLOC_ZERO(MEM_ACL_MODULE, p_sys_udf_entry->buffer, sizeof(sys_acl_udf_buffer_t));
            if (NULL == p_sys_udf_entry->buffer)
            {
                return CTC_E_NO_MEMORY;
            }
        }
        sal_memcpy(p_sys_udf_entry->buffer->key, tcam_key.data_entry, sizeof(ParserUdfCam_m));
        sal_memcpy(p_sys_udf_entry->buffer->mask, tcam_key.mask_entry, sizeof(ParserUdfCam_m));

        return CTC_E_NONE;
}

int32
_sys_usw_acl_check_udf_entry_key_field_union_son(uint8 lchip,  ctc_field_key_t* key_field, sys_acl_udf_entry_t  *p_sys_udf_entry, uint8 l3_type, uint8 l3_type_mask, uint8 l4_type, uint8 l4_type_mask)
{
    ctc_field_key_t key_field_tmp;

    sal_memset(&key_field_tmp, 0, sizeof(ctc_field_key_t));

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(key_field->type)
    {
    case CTC_FIELD_KEY_XDATA:
        {
            ctc_xdata_t* xdata = NULL;
            ctc_xdata_field_t* field = NULL;
            ds_t ds;
            uint8 sel0 = 0,sel1=0;
            uint8 temp_sel[2] = {0};
            uint8 temp_sel_valid[2] = {0};
            uint8 loop = 0;
            uint8 max_bit = 0;
            uint32 cmd = 0;

            CTC_PTR_VALID_CHECK(key_field->ext_data);
            xdata = (ctc_xdata_t*)(key_field->ext_data);

            CTC_MAX_VALUE_CHECK(xdata->num, 2);
            for(loop = 0; loop < xdata->num; loop++)
            {
                CTC_PTR_VALID_CHECK(xdata->fields);
                field = &xdata->fields[loop];
                if((field->width != CTC_XDATA_WIDTH_8 && field->width != CTC_XDATA_WIDTH_4) 
                    || ((CTC_CONST128 < field->offset+field->width)) 
                    || (0 != field->offset%field->width))
                {
                    return CTC_E_INVALID_PARAM;
                }
                CTC_MAX_VALUE_CHECK(field->data, (1 << field->width)-1);
                max_bit += field->width;
                if(max_bit > CTC_XDATA_WIDTH_8)
                {
                    return CTC_E_INVALID_PARAM;
                }
                if(field->width == CTC_XDATA_WIDTH_8)
                {
                    temp_sel[loop+1] = field->offset/CTC_XDATA_WIDTH_4 + 1;
                    temp_sel_valid[loop+1] = 1;
                }
                temp_sel[loop] = field->offset/CTC_XDATA_WIDTH_4;
                temp_sel_valid[loop] = 1;
            }

            if(p_usw_acl_master[lchip]->udf_xdata_used)
            {
                sal_memset(&ds, 0, sizeof(ds_t));
                cmd = DRV_IOR(IpeParserXCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds);
                sel0 = GetIpeParserXCtl(V,gUdfKey_0_nibbleSel_f, ds);
                sel1 = GetIpeParserXCtl(V,gUdfKey_1_nibbleSel_f, ds);
                if((temp_sel_valid[0] && sel0 != temp_sel[0]) || 
                    (temp_sel_valid[1] && sel1 != temp_sel[1]))
                {
                    return CTC_E_INVALID_PARAM;
                }
            }
        }
        break;
    case CTC_FIELD_KEY_PORT:
        {
            ctc_field_port_t *p_ctc_field_port;
            CTC_PTR_VALID_CHECK(key_field->ext_data);
            p_ctc_field_port = (ctc_field_port_t*)(key_field->ext_data);
            if(!DRV_FROM_TMM(lchip))
            {
                if (CTC_FIELD_PORT_TYPE_PORT_BITMAP != p_ctc_field_port->type)
                {
                    return CTC_E_INVALID_PARAM;
                }
            }
            else
            {
                if (CTC_FIELD_PORT_TYPE_PORT_CLASS != p_ctc_field_port->type)
                {
                    return CTC_E_INVALID_PARAM;
                }
                CTC_MAX_VALUE_CHECK(p_ctc_field_port->port_class_id, MCHIP_CAP(SYS_CAP_ACL_UDF_LABLE_MAX));
            }
        }
        break;
    case CTC_FIELD_KEY_L2_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, DRV_FROM_AT(lchip)?0x3:0x7);
        break;
    case CTC_FIELD_KEY_VLAN_NUM:
        CTC_MAX_VALUE_CHECK(key_field->data, 0x3);
        break;
    case CTC_FIELD_KEY_ETHER_TYPE:
        /*ethertype no need to check param valid*/
        break;
    case CTC_FIELD_KEY_L3_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_IP_OPTIONS:  /* D2,TM: u1_gIp */
    case CTC_FIELD_KEY_IP_FRAG:       /* D2,TM: u1_gIp */
        if (DRV_FROM_TMM(lchip))
        {
            SYS_ACL_UDF_UNION_CHECK(lchip,l3_type_mask, l3_type, SYS_ACL_UDF_UNION_CHK_IP);
        }
        else
        {
            if (p_sys_udf_entry->mpls_num)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
        if(key_field->type == CTC_FIELD_KEY_IP_OPTIONS )
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(key_field->data, CTC_IP_FRAG_MAX - 1);
        }
        break;
    case CTC_FIELD_KEY_LABEL_NUM:  /* D2,TM: u1_gMpls */
    case CTC_FIELD_KEY_CW_EXIST:
    case CTC_FIELD_KEY_IP_OVER_MPLS:
    case CTC_FIELD_KEY_IPV6_OVER_MPLS:
        if (DRV_FROM_TMM(lchip))
        {
           SYS_ACL_UDF_UNION_CHECK(lchip,l3_type_mask, l3_type, SYS_ACL_UDF_UNION_CHK_MPLS);
        }
        else
        {
            if(CTC_FIELD_KEY_LABEL_NUM != key_field->type)
            {
                return CTC_E_NOT_SUPPORT;
            }
            if (p_sys_udf_entry->ip_op || p_sys_udf_entry->ip_frag)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
        if(CTC_FIELD_KEY_LABEL_NUM == key_field->type)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 9);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;
    case CTC_FIELD_KEY_L4_TYPE:
        CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        break;
    case CTC_FIELD_KEY_GRE_FLAGS:    /* D2,TM: u2_gGre */
    case CTC_FIELD_KEY_GRE_PROTOCOL_TYPE:
        if (DRV_FROM_TMM(lchip))
        {
            SYS_ACL_UDF_UNION_CHECK(lchip,l4_type_mask, l4_type, SYS_ACL_UDF_UNION_CHK_GRE);
        }
        else
        {
            if (p_sys_udf_entry->l4_type != CTC_PARSER_L4_TYPE_GRE || p_sys_udf_entry->ip_protocol)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
        CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
        break;
    case CTC_FIELD_KEY_L4_DST_PORT:   /* D2,TM: u2_gTcpUdp */
    case CTC_FIELD_KEY_L4_SRC_PORT:
    case CTC_FIELD_KEY_L4_USER_TYPE: /* D2,TM: u2_gOthers_layer3HeaderProtocol */
    case CTC_FIELD_KEY_TCP_OPTIONS:
        if (DRV_FROM_TMM(lchip) && (CTC_FIELD_KEY_L4_USER_TYPE != key_field->type))
        {
            SYS_ACL_UDF_UNION_CHECK(lchip,l4_type_mask, l4_type, SYS_ACL_UDF_UNION_CHK_TCP_UDP);
        }
        else
        {
            if ((p_sys_udf_entry->l4_type != CTC_PARSER_L4_TYPE_TCP
                && p_sys_udf_entry->l4_type != CTC_PARSER_L4_TYPE_UDP
            && p_sys_udf_entry->l4_type != CTC_PARSER_L4_TYPE_RDP
            && p_sys_udf_entry->l4_type != CTC_PARSER_L4_TYPE_SCTP
            && p_sys_udf_entry->l4_type != CTC_PARSER_L4_TYPE_DCCP)
            || p_sys_udf_entry->ip_protocol)
            {
                return CTC_E_INVALID_PARAM;
            }
        }

        if (key_field->type == CTC_FIELD_KEY_L4_DST_PORT ||
            key_field->type == CTC_FIELD_KEY_L4_SRC_PORT)
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xFFFF);
            if(DRV_ENUM(DRV_PARSER_L4_USER_TYPE_UDP_VXLAN) == GetParserUdfCam(V, layer4UserType_f, p_sys_udf_entry->buffer->key))
            {
                return CTC_E_INVALID_PARAM;
            }
        }
        else  if (key_field->type == CTC_FIELD_KEY_L4_USER_TYPE )
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 0xF);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(key_field->data, 1);
        }
        break;
    case CTC_FIELD_KEY_L3_EXT_TYPE: /* TMM */
    case CTC_FIELD_KEY_IP_PROTOCOL:  /* D2,TM: u2_gOthers_layer3HeaderProtocol  */
        if (DRV_FROM_TMM(lchip))
        {
            SYS_ACL_UDF_UNION_CHECK(lchip,l3_type_mask, l3_type, SYS_ACL_UDF_UNION_CHK_IP);
        }
        else
        {
            if ((p_sys_udf_entry->l4_type == CTC_PARSER_L4_TYPE_TCP
                || p_sys_udf_entry->l4_type == CTC_PARSER_L4_TYPE_UDP
            || p_sys_udf_entry->l4_type == CTC_PARSER_L4_TYPE_RDP
            || p_sys_udf_entry->l4_type == CTC_PARSER_L4_TYPE_SCTP
            || p_sys_udf_entry->l4_type == CTC_PARSER_L4_TYPE_DCCP
            || p_sys_udf_entry->l4_type == CTC_PARSER_L4_TYPE_GRE))
            {
                return CTC_E_INVALID_PARAM;
            }
        }

        CTC_MAX_VALUE_CHECK(key_field->data, (key_field->type == CTC_FIELD_KEY_L3_EXT_TYPE) ? 3 : 0xFF);
        break;
    case CTC_FIELD_KEY_UDF_ENTRY_VALID:
    case CTC_FIELD_KEY_METADATA:
        break;
    default:
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_check_udf_entry_key_field_union(uint8 lchip,  uint32 udf_id, ctc_field_key_t* key_field)
{
    int32  ret = CTC_E_NONE;
    sys_acl_udf_entry_t    *p_sys_udf_entry = NULL;
    uint8 l3_type = 0;
    uint8 l3_type_mask = 0;
    uint8 l4_type = 0;
    uint8 l4_type_mask = 0;

   SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    _sys_usw_acl_get_udf_info(lchip, udf_id, &p_sys_udf_entry);
    if (!p_sys_udf_entry || !p_sys_udf_entry->key_index_used)
    {
        return CTC_E_NOT_EXIST;
    }

    if(p_sys_udf_entry->is_sudf) /* service udf */
    {
        return CTC_E_INVALID_PARAM;
    }

    if(DRV_FROM_TMM(lchip))
    {
        if(p_sys_udf_entry->is_installed)
        {
            CTC_ERROR_RETURN(_sys_usw_acl_udf_rebuild_buffer_from_hw( lchip, p_sys_udf_entry));
        }
        l3_type = GetParserUdfCam(V, layer3Type_f, p_sys_udf_entry->buffer->key);
        l3_type_mask = GetParserUdfCam(V, layer3Type_f, p_sys_udf_entry->buffer->mask);
        l4_type = GetParserUdfCam(V, layer4Type_f, p_sys_udf_entry->buffer->key);
        l4_type_mask = GetParserUdfCam(V, layer4Type_f, p_sys_udf_entry->buffer->mask);
    }

    ret = _sys_usw_acl_check_udf_entry_key_field_union_son(lchip, key_field, p_sys_udf_entry,l3_type, l3_type_mask, l4_type, l4_type_mask);

    /* error rollback */
    if(ret < 0)
    {
        if((p_sys_udf_entry->is_installed) && (p_sys_udf_entry->buffer))
        {
            mem_free(p_sys_udf_entry->buffer);
        }
    }

    return ret;
}

int32 _sys_usw_acl_set_udf_entry_key_field_union(uint8 lchip,  uint32 udf_id, ctc_field_key_t* key_field,uint8 is_add)
{
    sys_acl_udf_entry_t    *p_sys_udf_entry;

    _sys_usw_acl_get_udf_info(lchip, udf_id, &p_sys_udf_entry);
    if(!p_sys_udf_entry || !p_sys_udf_entry->key_index_used)
    {
        return CTC_E_NOT_EXIST;
    }
    switch(key_field->type)
    {
    case CTC_FIELD_KEY_XDATA:
        p_usw_acl_master[lchip]->udf_xdata_used = is_add ? 1: p_usw_acl_master[lchip]->udf_xdata_used;
        break;
    case CTC_FIELD_KEY_IP_OPTIONS:
        p_sys_udf_entry->ip_op = is_add ? 1:0;
        break;
    case CTC_FIELD_KEY_IP_FRAG:
        p_sys_udf_entry->ip_frag = is_add ? 1:0;
        break;
    case CTC_FIELD_KEY_LABEL_NUM:
        p_sys_udf_entry->mpls_num = is_add ? 1:0;
        break;
    case CTC_FIELD_KEY_L4_TYPE:
        p_sys_udf_entry->l4_type = is_add ? key_field->data:0;
        break;
    case CTC_FIELD_KEY_IP_PROTOCOL:
        p_sys_udf_entry->ip_protocol = is_add ? 1:0;
        break;
    }
    return CTC_E_NONE;
}

int32
sys_usw_acl_check_udf_ad_id_mode(uint8 lchip, ctc_acl_classify_udf_t* udf_entry)
{
    SYS_USW_ACL_LOCK(lchip);
    if((udf_entry->shared_udf && SYS_ACL_UDF_AD_ID_MODE_DFT == SYS_ACL_UDF_AD_ID_MODE(lchip))||
        (!udf_entry->shared_udf && SYS_ACL_UDF_AD_ID_MODE_USER == SYS_ACL_UDF_AD_ID_MODE(lchip)))

    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "udf_ad_id asign error !!! udf_ad_id_mode:%d\n", SYS_ACL_UDF_AD_ID_MODE(lchip));
        SYS_USW_ACL_ERROR_RETURN_UNLOCK(CTC_E_INVALID_PARAM);
    }
    SYS_USW_ACL_UNLOCK(lchip);
    return CTC_E_NONE;
}
int32
sys_usw_acl_count_udf_entry(uint8 lchip, ctc_acl_classify_udf_t* udf_entry, uint8 is_add)
{
    SYS_USW_ACL_LOCK(lchip);
    if(is_add)
    {
        p_usw_acl_master[lchip]->udf_entry_cnt++;
        if(SYS_ACL_UDF_AD_ID_MODE_NONE == SYS_ACL_UDF_AD_ID_MODE(lchip))
        {
            SYS_ACL_UDF_AD_ID_MODE(lchip) = udf_entry->shared_udf?SYS_ACL_UDF_AD_ID_MODE_USER:SYS_ACL_UDF_AD_ID_MODE_DFT;
        }
    }
    else
    {
        if( 0 == --p_usw_acl_master[lchip]->udf_entry_cnt )
        {
            SYS_ACL_UDF_AD_ID_MODE(lchip) = SYS_ACL_UDF_AD_ID_MODE_NONE;
        }
    }
    SYS_USW_ACL_UNLOCK(lchip);
    return CTC_E_NONE;
}

#define _ACL_LEAGUE_

/*
    This function is used to travese one block and store entry to list.
*/
int32 _sys_usw_acl_league_traverse_block(uint8 lchip, uint8 tmp_block_id, uint16* entry_base,
                                                ctc_linklist_t** node_list, uint16* sub_entry_num,
                                                uint16* sub_free_num, sys_usw_acl_league_node_t** node_array)
{
    uint8  key_size;
    uint8  step = 1;
    uint16 start;
    uint16 end;
    uint16 offset;
    uint16 tmp_count;
    uint16 sub_total_count;
    sys_usw_acl_league_node_t* p_node = NULL;
    ctc_fpa_block_t* p_b = &SYS_ACL_BLOCK(lchip, tmp_block_id).fpab;
    ctc_fpa_entry_t* p_e = NULL;
    sys_acl_entry_t* p_entry = NULL;
    if(p_b == NULL)
    {
        return CTC_E_INVALID_PARAM;
    }

    for(key_size=CTC_FPA_KEY_SIZE_80; key_size < CTC_FPA_KEY_SIZE_NUM; step *=2, key_size++)
    {
        if(0 == p_b->sub_entry_count[key_size])
        {
            continue;
        }
        sub_total_count = p_b->sub_entry_count[key_size]- p_b->sub_free_count[key_size];
        tmp_count = 0;
        sub_entry_num[key_size] += p_b->sub_entry_count[key_size];
        sub_free_num[key_size] += p_b->sub_free_count[key_size];
        start = p_b->start_offset[key_size];
        end = start + (p_b->sub_entry_count[key_size])*step;

        for(offset=start,tmp_count=0; (offset < end)&&(tmp_count<sub_total_count); offset+=step)
        {
            p_e = p_b->entries[offset];
            if(NULL == p_e)
            {
                continue;
            }
            tmp_count++;
            if(NULL == (p_node = mem_malloc(MEM_ACL_MODULE, sizeof(sys_usw_acl_league_node_t))))
            {
                return CTC_E_NO_MEMORY;
            }
            sal_memset(p_node, 0, sizeof(sys_usw_acl_league_node_t));
            p_node->entry_id = p_e->entry_id;
            p_node->prio = p_e->priority;
            p_node->old_index = offset+(*entry_base);
            p_node->step = p_e->step;
            p_entry = _ctc_container_of(p_e, sys_acl_entry_t, fpae);
            p_node->old_block_id  = p_entry->group->group_info.block_id;
            ctc_listnode_add_sort(node_list[key_size], p_node);
            node_array[p_node->old_index] = p_node;
        }
    }
    (*entry_base) += p_b->entry_count;
    return CTC_E_NONE;
}
/*
    This function  is used to modified soft table and move entry when needed
*/
int32 _sys_usw_acl_league_move_entry(uint8 lchip, ctc_linklist_t** node_list, ctc_fpa_entry_t** p_tmp_entries,
                                                uint16* sub_entry_num, uint8 block_id, sys_usw_acl_league_node_t** node_array)
{
    ctc_listnode_t* node;
    uint16 new_idx = 0;
    uint16 tmp_entry_cnt = 0;
    uint32 old_key;
    uint32 old_ad;
    uint32 old_hw_idx;
    uint32 new_key;
    uint32 new_ad;
    uint32 new_hw_idx;
    uint32 cmd = 0;
    sys_acl_entry_t* p_e = NULL;
    sys_acl_entry_t* p_tmp_entry = NULL;
    uint16 base = 0;
    uint8  key_size = 0;
    uint8  step = 1;
    uint16 tmp_idx = 0;
    sys_usw_acl_league_node_t* p_node = NULL;

    for(key_size=CTC_FPA_KEY_SIZE_80; key_size < CTC_FPA_KEY_SIZE_NUM; key_size++)
    {
        tmp_entry_cnt = 0;
        CTC_LIST_LOOP(node_list[key_size], p_node, node)
        {
            new_idx = base+(tmp_entry_cnt*step);
            tmp_entry_cnt++;
            _sys_usw_acl_get_entry_by_eid(lchip, p_node->entry_id, &p_e);

            /*temp change block id for get table used*/
            p_e->group->group_info.block_id = p_node->old_block_id;
            SYS_ACL_GET_TBL_FUNC(lchip, p_e, &old_key, &old_ad, &old_hw_idx);

            p_e->group->group_info.block_id = block_id;
            p_e->fpae.offset_a = new_idx;
            p_tmp_entries[new_idx] = &(p_e->fpae);

            if(new_idx != p_node->old_index && (p_e->fpae.flag == FPA_ENTRY_FLAG_INSTALLED))
            {
                tbl_entry_t         tcam_key;
                sys_acl_buffer_t  tmp_buffer;
                sys_acl_buffer_t*   p_new_buffer = NULL;
                uint8 tmp_block_id = 0;

                /*1. if the entry already exists at the location to be written, the entry needs to be read into buffer first*/
                for(tmp_idx=new_idx/8*8; tmp_idx < new_idx/8*8+8; tmp_idx++)
                {
                    if(node_array[tmp_idx] && (node_array[tmp_idx]->p_buffer == NULL) && node_array[tmp_idx]->status == 0 &&
                        ((tmp_idx <= new_idx && new_idx < tmp_idx+node_array[tmp_idx]->step) || (tmp_idx > new_idx && tmp_idx < new_idx+step)))
                    {
                        _sys_usw_acl_get_entry_by_eid(lchip, node_array[tmp_idx]->entry_id, &p_tmp_entry);
                        if(p_tmp_entry->fpae.flag == FPA_ENTRY_FLAG_UNINSTALLED)
                        {
                            node_array[tmp_idx]->status = 1;
                            continue;
                        }
                        /*temp change block id for get table used*/
                        tmp_block_id = p_tmp_entry->group->group_info.block_id;
                        p_tmp_entry->group->group_info.block_id = node_array[tmp_idx]->old_block_id;
                        SYS_ACL_GET_TBL_FUNC(lchip, p_tmp_entry, &new_key, &new_ad, &new_hw_idx);
                        p_tmp_entry->group->group_info.block_id = tmp_block_id;

                        sal_memset(&tcam_key, 0, sizeof(tcam_key));
                        MALLOC_ZERO(MEM_ACL_MODULE, p_new_buffer, sizeof(sys_acl_buffer_t));
                        if(!p_new_buffer)
                        {
                            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No resource in ASIC \n");
                    		return CTC_E_NO_RESOURCE;
                        }

                        {
                            cmd = DRV_IOR(new_key, DRV_ENTRY_FLAG);
                            tcam_key.data_entry = p_new_buffer->key;
                            tcam_key.mask_entry = p_new_buffer->mask;
                            CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_KEY_INDEX(new_hw_idx, p_tmp_entry->fpae.real_step),
                                                DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));

                            cmd = DRV_IOR(new_ad, DRV_ENTRY_FLAG);
                            CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_AD_INDEX(new_hw_idx, p_tmp_entry->fpae.real_step),
                                                DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), p_new_buffer->action));
                        }
                        node_array[tmp_idx]->p_buffer = p_new_buffer;
                    }
                }

                /*2. if old entry in buffer, recovery from buffer*/
                SYS_ACL_GET_TBL_FUNC(lchip, p_e, &new_key, &new_ad, &new_hw_idx);
                if(node_array[p_node->old_index]->p_buffer)
                {
                    cmd = DRV_IOW(new_ad, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_AD_INDEX(new_hw_idx, p_e->fpae.real_step),
                    DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &(node_array[p_node->old_index]->p_buffer->action)));

                    cmd = DRV_IOW(new_key, DRV_ENTRY_FLAG);
                    tcam_key.data_entry = node_array[p_node->old_index]->p_buffer->key;
                    tcam_key.mask_entry = node_array[p_node->old_index]->p_buffer->mask;
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_KEY_INDEX(new_hw_idx, p_e->fpae.real_step),
                                        DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));
                    mem_free(node_array[p_node->old_index]->p_buffer);

                }
                else
                {
                    cmd = DRV_IOR(old_key, DRV_ENTRY_FLAG);
                    tcam_key.data_entry = tmp_buffer.key;
                    tcam_key.mask_entry = tmp_buffer.mask;
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_KEY_INDEX(old_hw_idx, p_e->fpae.real_step),
                                        DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));
                    cmd = DRV_IOR(old_ad, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_AD_INDEX(old_hw_idx, p_e->fpae.real_step),
                                        DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tmp_buffer.action));

                    cmd = DRV_IOW(new_ad, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_AD_INDEX(new_hw_idx, p_e->fpae.real_step),
                                        DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tmp_buffer.action));
                    cmd = DRV_IOW(new_key, DRV_ENTRY_FLAG);
                    tcam_key.data_entry = tmp_buffer.key;
                    tcam_key.mask_entry = tmp_buffer.mask;
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_KEY_INDEX(new_hw_idx, p_e->fpae.real_step),
                                        DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));

                    cmd = DRV_IOD(old_key, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, SYS_ACL_MAP_DRV_KEY_INDEX(old_hw_idx, p_e->fpae.real_step),
                                        DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));
                }
                node_array[p_node->old_index]->status = 1;
            }
        }
        base += sub_entry_num[key_size]*step;
        step *= 2;
    }
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_TCAM_ENTRY, 1);
    return CTC_E_NONE;
}
/*
 league1: working level
 league2: merged level
*/

int32
_sys_usw_acl_set_league_merge(uint8 lchip, sys_acl_league_t* p_league1, sys_acl_league_t* p_league2, uint8 auto_en)
{
    uint8 lkup_level1 = 0;
    uint8 lkup_level2 = 0;
    uint8 same_size = 0;
    uint8 m_640 = 0;
    uint32 entry_enum = 0;
    sys_acl_block_t *pb1 = NULL, *pb2 = NULL;
    ctc_slistnode_t* group_node;
    ctc_slistnode_t* n_group_node;
    sys_acl_group_t* pg = NULL;

    if (p_league2->block_id >= ACL_IGS_BLOCK_MAX_NUM)
    {
        lkup_level1 = p_league1->block_id - ACL_IGS_BLOCK_MAX_NUM;
        lkup_level2 = p_league2->block_id - ACL_IGS_BLOCK_MAX_NUM;
    }
    else
    {
        lkup_level1 = p_league1->block_id;
        lkup_level2 = p_league2->block_id;
    }

    pb1 = &SYS_ACL_BLOCK(lchip, p_league1->block_id);
    pb2 = &SYS_ACL_BLOCK(lchip, p_league2->block_id);
    same_size = pb1->fpab.same_size;
    m_640 = same_size?1:8;
    {
        CTC_BIT_SET(p_league1->lkup_level_bitmap, lkup_level2);
    }

    CTC_BIT_UNSET(p_league2->lkup_level_bitmap,lkup_level2);
    p_league2->merged_to = lkup_level1;

    entry_enum = pb2->entry_num;
    p_league1->lkup_level_start[lkup_level2] = pb1->fpab.entry_count;
    p_league1->lkup_level_count[lkup_level2] = entry_enum;
    pb1->fpab.entry_count += entry_enum;

    /*The following soft table does not need to be modifed when auto mode is enabled*/
    if(!auto_en)
    {
        pb1->fpab.free_count  += entry_enum;
        pb1->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_640] += entry_enum / m_640;
        pb1->fpab.sub_free_count[CTC_FPA_KEY_SIZE_640] += entry_enum / m_640;
        pb1->fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;
    }
    /*free merged block*/
    sal_memset(&(pb2->fpab), 0, sizeof(ctc_fpa_block_t)-sizeof(sys_acl_entry_t*)) ;
    mem_free(pb2->fpab.entries);
    CTC_SLIST_LOOP_DEL(pb2->group_list, group_node, n_group_node)
    {
        pg = _ctc_container_of(group_node, sys_acl_group_t, head);
        pg->group_info.block_id = lkup_level1;
        ctc_slist_add_tail(pb1->group_list, group_node);
    }
    ctc_slist_free(pb2->group_list);
    pb2->group_list = NULL;
    return CTC_E_NONE;
}



/*
 league1: working level
 league2: canceled level
*/
int32
_sys_usw_acl_set_league_cancel(uint8 lchip, sys_acl_league_t* p_league1, sys_acl_league_t* p_league2)
{
    /*uint8 lkup_level1= 0;*/
    uint8 lkup_level2 = 0;
    uint32 entry_num = 0;
    ctc_fpa_block_t *pb1 = NULL;
    sys_acl_block_t *p_acl_block1 = NULL;
    sys_acl_block_t *p_acl_block2 = NULL;
 /*    uint32 sub_entry_count = 0;*/
   /*  uint32 sub_free_count = 0;*/

    uint16 tmp_count = 0;
    //uint16 start_offset = 0;
    //uint16 entry_size;
    uint8 same_size = 0;
    uint8 m_160 = 0;
    uint8 m_320 = 0;
    uint8 m_640 = 0;
    uint8  block_id1 = p_league1->block_id;
    uint8  block_id2 = p_league2->block_id;

    /*lkup_level1 = ((block_id1 >= ACL_IGS_BLOCK_MAX_NUM) ? block_id1 - ACL_IGS_BLOCK_MAX_NUM: block_id1);*/
    lkup_level2 = ((block_id2 >= ACL_IGS_BLOCK_MAX_NUM) ? block_id2 - ACL_IGS_BLOCK_MAX_NUM: block_id2);

    p_acl_block1 = &SYS_ACL_BLOCK(lchip, block_id1);
    p_acl_block2 = &SYS_ACL_BLOCK(lchip, block_id2);
    entry_num = p_acl_block2->entry_num;
    same_size = p_acl_block1->fpab.same_size;
    m_160 = same_size?1:2;
    m_320 = same_size?1:4;
    m_640 = same_size?1:8;

    pb1 = &p_acl_block1->fpab;
    /*free cancelled block resources*/
    if(pb1->free_count < entry_num)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "free cancelled block resources:src block :%d dst block:%d\n",
        block_id1,block_id2);

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "free cancelled block resources:entry_num :%d free_count:%d\n",
        entry_num,pb1->free_count);

        return CTC_E_INVALID_CONFIG;
    }
    else
    {
        pb1->entry_count -= entry_num;
        pb1->free_count -= entry_num;
        CTC_BIT_UNSET(p_league1->lkup_level_bitmap, lkup_level2);
    }

    if (pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] && p_league1->lkup_level_start[lkup_level2] >= pb1->start_offset[CTC_FPA_KEY_SIZE_640])
    {
        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] -= entry_num/m_640;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_640] -= entry_num/m_640;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;
    }
    else if (pb1->sub_entry_count[CTC_FPA_KEY_SIZE_320] && p_league1->lkup_level_start[lkup_level2] >= pb1->start_offset[CTC_FPA_KEY_SIZE_320])
    {
        tmp_count = pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] * m_640;
        pb1->start_offset[CTC_FPA_KEY_SIZE_640] = p_league1->lkup_level_start[lkup_level2];
        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;

        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_320] -= (entry_num-tmp_count)/m_320;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_320] -= (entry_num-tmp_count)/m_320;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_320] = 0;
    }
    else if (pb1->sub_entry_count[CTC_FPA_KEY_SIZE_160] && p_league1->lkup_level_start[lkup_level2] >= pb1->start_offset[CTC_FPA_KEY_SIZE_160])
    {
        tmp_count = pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] * m_640 + \
                    pb1->sub_entry_count[CTC_FPA_KEY_SIZE_320] * m_320;

        pb1->start_offset[CTC_FPA_KEY_SIZE_640] = p_league1->lkup_level_start[lkup_level2];
        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;

        pb1->start_offset[CTC_FPA_KEY_SIZE_320] = p_league1->lkup_level_start[lkup_level2];
        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_320] = 0;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_320] = 0;

        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_160] -= (entry_num-tmp_count)/m_160;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_160] -= (entry_num-tmp_count)/m_160;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_160] = 0;
    }
    else if (pb1->sub_entry_count[CTC_FPA_KEY_SIZE_80] && p_league1->lkup_level_start[lkup_level2] >= pb1->start_offset[CTC_FPA_KEY_SIZE_80])
    {
        tmp_count = pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] * m_640 + \
                    pb1->sub_entry_count[CTC_FPA_KEY_SIZE_320] * m_320 + \
                    pb1->sub_entry_count[CTC_FPA_KEY_SIZE_160] * m_160;

        pb1->start_offset[CTC_FPA_KEY_SIZE_640] = p_league1->lkup_level_start[lkup_level2];
        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;

        pb1->start_offset[CTC_FPA_KEY_SIZE_320] = p_league1->lkup_level_start[lkup_level2];
        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_320] = 0;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_320] = 0;

        pb1->start_offset[CTC_FPA_KEY_SIZE_160] = p_league1->lkup_level_start[lkup_level2];
        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_160] = 0;
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_160] = 0;
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_160] = 0;

        pb1->sub_entry_count[CTC_FPA_KEY_SIZE_80] -= (entry_num-tmp_count);
        pb1->sub_free_count[CTC_FPA_KEY_SIZE_80] -= (entry_num-tmp_count);
        pb1->sub_rsv_count[CTC_FPA_KEY_SIZE_80] = 0;
    }
    p_league1->lkup_level_start[lkup_level2] = 0;
    p_league1->lkup_level_count[lkup_level2] = 0;

    /*init new block */
    CTC_ERROR_RETURN(sys_usw_acl_fpa_block_init(lchip, block_id2));
    return CTC_E_NONE;
}

int32
_sys_usw_acl_get_entry_count_on_lkup_level(uint8 lchip, uint8 block_id, uint8 level, uint32* count)
{
    uint8 step = 0;
    uint16 block_idx = 0;
    uint16 start_idx = 0;
    uint16 end_idx = 0;
    uint32 tmp_count = 0;
    sys_acl_block_t* pb = NULL;
    sys_acl_league_t* p_sys_league = NULL;
    uint8 same_size = 0;

    CTC_PTR_VALID_CHECK(count);

    pb = &SYS_ACL_BLOCK(lchip, block_id);
    p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
    start_idx = p_sys_league->lkup_level_start[level];
    end_idx = p_sys_league->lkup_level_start[level] + p_sys_league->lkup_level_count[level];
    *count = 0;

   same_size = SYS_ACL_BLOCK(lchip, block_id).fpab.same_size;


    step  = 1;
    for (block_idx = start_idx; block_idx < end_idx; block_idx = block_idx + step)
    {
        if((block_idx >= pb->fpab.start_offset[CTC_FPA_KEY_SIZE_640]) && (pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_640]))      /*640 bit key*/
        {
            step = 8;
        }
        else if(block_idx >= pb->fpab.start_offset[CTC_FPA_KEY_SIZE_320] && (pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_320]))   /*320 bit key*/
        {
            step = 4;
        }
        else if(block_idx >= pb->fpab.start_offset[CTC_FPA_KEY_SIZE_160] && (pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_160]))   /*160 bit key*/
        {
            step = 2;
        }
        else                                            /*80 bit key*/
        {
            step = 1;
        }

        step = same_size?1:step;

        if (pb->fpab.entries[block_idx])
        {
            tmp_count++;
        }
    }

    *count = tmp_count;

    return CTC_E_NONE;
}
int32 _sys_usw_acl_get_ordered_league_block(uint8 lchip, uint8 block_id, uint8 size, ctc_acl_league_t* league)
{
    uint8 block_cnt = 0;
    uint8 part_num;
    uint8 block_base = league->dir == CTC_INGRESS ? 0 : ACL_IGS_BLOCK_MAX_NUM;
    sys_acl_block_t*  pb;

    pb = &SYS_ACL_BLOCK(lchip, block_id);
    while(pb && block_cnt < league->list_cnt)
    {
        part_num = 0;
        do
        {
            league->leagued_list[block_cnt] = pb->block_id+part_num-block_base;
            block_cnt++;
            part_num++;
        }while(part_num < size && league->list_cnt);
        pb = pb->next;
    }
    league->list_cnt = block_cnt;
    return CTC_E_NONE;
}

int32
_sys_usw_acl_replace_dma_with_sdb_copy(uint8 lchip, ctc_acl_replace_t* p_replace, uint8 merge_size)
{

    uint8 part;
    uint8 loop;
    uint32 cfg_addr;
    sys_dma_tbl_rw_t dma_rw;
    uint32 src_table;
    uint32 dest_table;
    uint32* p_tmp_addr;
    uint32 hw_ad_tbl = DsAcl0Ingress_t;
    uint32 hw_key_tbl = DsProgrammingAclTcam0_t;
    uint32 hw_tcam_mem = DRV_FROM_AT(lchip) ? ProgramIngAclTcamMem_t : ProgramAclTcamMem_t;
    uint16 entry_num = 0;

    entry_num = DRV_TABLE_MAX_INDEX(lchip, hw_tcam_mem)/ACL_IGS_BLOCK_MAX_NUM;
    if(CTC_EGRESS == p_replace->dir)
    {
        hw_ad_tbl = DsAcl0Egress_t;
        hw_key_tbl = DsEgrProgrammingAclTcam0_t;
        hw_tcam_mem = ProgramEgrAclTcamMem_t;
        entry_num = DRV_TABLE_MAX_INDEX(lchip, hw_tcam_mem)/ACL_EGS_BLOCK_MAX_NUM;
    }

    sal_memset(&dma_rw, 0, sizeof(dma_rw));
    SYS_ACL_PART_LOOP(part, merge_size)
    {
        src_table = hw_ad_tbl + p_replace->src_lkup_level + part;
        dest_table = hw_ad_tbl + p_replace->dest_lkup_level + part;
        for(loop=0; loop < DRV_TABLE_MAX_INDEX(lchip, hw_ad_tbl)/SYS_USW_ACL_DMA_OP_SIZE; loop++)
        {
            p_tmp_addr = drv_sdb_read(lchip, src_table, loop*SYS_USW_ACL_DMA_OP_SIZE, DRV_TABLE_ENTRY_SIZE(lchip, hw_ad_tbl), 0);
            sal_memcpy(p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf, p_tmp_addr, SYS_USW_ACL_DMA_OP_SIZE*TABLE_ENTRY_SIZE(lchip, hw_ad_tbl));
            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE, &cfg_addr);

            dma_rw.tbl_addr = cfg_addr;
            dma_rw.entry_num = SYS_USW_ACL_DMA_OP_SIZE;
            dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip, hw_ad_tbl);
            dma_rw.buffer = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf;
            dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, hw_ad_tbl);
            dma_rw.user_dma_mode = 1;
            MCHIP_DMA(lchip)->dma_write_table(lchip, &dma_rw);

            p_tmp_addr = drv_sdb_read(lchip, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE, DRV_TABLE_ENTRY_SIZE(lchip, hw_ad_tbl), 0);
            sal_memcpy(p_tmp_addr, dma_rw.buffer, SYS_USW_ACL_DMA_OP_SIZE*TABLE_ENTRY_SIZE(lchip, hw_ad_tbl));
        }

        src_table = hw_tcam_mem;
        dest_table = hw_tcam_mem;
        for(loop=0; loop < DRV_TABLE_MAX_INDEX(lchip, hw_key_tbl)/SYS_USW_ACL_DMA_OP_SIZE; loop++)
        {
            p_tmp_addr = drv_sdb_read(lchip, src_table, loop*SYS_USW_ACL_DMA_OP_SIZE+entry_num*(p_replace->src_lkup_level + part), TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem), 0);
            sal_memcpy(p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf, p_tmp_addr, SYS_USW_ACL_DMA_OP_SIZE*TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem));
            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE+entry_num*(p_replace->dest_lkup_level + part), &cfg_addr);

            dma_rw.tbl_addr = cfg_addr;
            dma_rw.entry_num = SYS_USW_ACL_DMA_OP_SIZE;
            dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip, hw_tcam_mem);
            dma_rw.buffer = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf;
            dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem);
            dma_rw.user_dma_mode = 1;
            MCHIP_DMA(lchip)->dma_write_table(lchip, &dma_rw);

            p_tmp_addr = drv_sdb_read(lchip, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE+entry_num*(p_replace->dest_lkup_level + part), TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem), 0);
            sal_memcpy(p_tmp_addr, dma_rw.buffer, SYS_USW_ACL_DMA_OP_SIZE*TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem));

        }

        /*mv data for tcam scan*/
        if (drv_ser_get_tcam_scan_enable(lchip))
        {
            uint32 src_mem_id = 0;
            uint32 dst_mem_id = 0;
            src_mem_id = SYS_USW_ACL_MAP_MEM2DESC((p_replace->src_lkup_level +  part));
            dst_mem_id = SYS_USW_ACL_MAP_MEM2DESC((p_replace->dest_lkup_level +  part));
            CTC_ERROR_RETURN(sys_usw_dma_copy_desc_data(lchip, SYS_DMA_TCAM_SCAN_CHAN_ID, src_mem_id, dst_mem_id));
        }
    }
    return 0;
}


int32
_sys_usw_acl_replace_dma_with_sdb_delete(uint8 lchip, ctc_acl_replace_t* p_replace, uint8 merge_size)
{

    uint8 part;
    uint8 loop;
    uint32 cfg_addr;
    sys_dma_tbl_rw_t dma_rw;
    uint32 dest_table;
    uint32* p_tmp_addr;
    uint32 hw_key_tbl = DsProgrammingAclTcam0_t;
    uint32 hw_tcam_mem = DRV_FROM_AT(lchip) ? ProgramIngAclTcamMem_t : ProgramAclTcamMem_t;

    if(CTC_EGRESS == p_replace->dir)
    {
        hw_key_tbl = DsEgrProgrammingAclTcam0_t;
        hw_tcam_mem = ProgramEgrAclTcamMem_t;
    }

    sal_memset(&dma_rw, 0, sizeof(dma_rw));
    sal_memset(p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf, 0, SYS_USW_ACL_DMA_OP_SIZE*TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem));
    dma_rw.entry_num = SYS_USW_ACL_DMA_OP_SIZE;
    dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip, hw_tcam_mem);
    dma_rw.buffer = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf;
    dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem);
    dma_rw.user_dma_mode = 1;
    SYS_ACL_PART_LOOP(part, merge_size)
    {
        dest_table = hw_tcam_mem;
        for(loop=0; loop < DRV_TABLE_MAX_INDEX(lchip,hw_key_tbl)/SYS_USW_ACL_DMA_OP_SIZE; loop++)
        {
            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE+DRV_TABLE_MAX_INDEX(lchip, hw_key_tbl)*(p_replace->src_lkup_level + part), &cfg_addr);

            dma_rw.tbl_addr = cfg_addr;
            MCHIP_DMA(lchip)->dma_write_table(lchip, &dma_rw);
            p_tmp_addr = drv_sdb_read(lchip, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE+DRV_TABLE_MAX_INDEX(lchip, hw_key_tbl)*(p_replace->src_lkup_level + part), TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem), 0);
            sal_memset(p_tmp_addr, 0, SYS_USW_ACL_DMA_OP_SIZE*TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem));
        }

        /*clear data for tcam scan*/
        if (drv_ser_get_tcam_scan_enable(lchip))
        {
            uint32 src_mem_id = 0;
            src_mem_id = SYS_USW_ACL_MAP_MEM2DESC((p_replace->src_lkup_level +  part));
            CTC_ERROR_RETURN(sys_usw_dma_copy_desc_data(lchip, SYS_DMA_TCAM_SCAN_CHAN_ID, src_mem_id, src_mem_id));
        }
    }

    return CTC_E_NONE;
}
int32
_sys_usw_acl_replace_dma_copy(uint8 lchip, ctc_acl_replace_t* p_replace, uint8 merge_size)
{
    uint16 loop;
    uint16 loop1;
    uint32 cfg_addr;
    sys_dma_tbl_rw_t dma_rw;
    uint32 src_table;
    uint32 dest_table;
    uint32* p_data;
    uint32* p_mask;
    uint32  mask_tmp;
    uint32 hw_ad_tbl = DsAcl0Ingress_t;
    uint32 hw_key_tbl = DsProgrammingAclTcam0_t;
    uint32 hw_tcam_mem = DRV_FROM_AT(lchip) ? ProgramIngAclTcamMem_t : ProgramAclTcamMem_t;
    uint16 entry_num = 0;
    uint8 part;

    entry_num = DRV_TABLE_MAX_INDEX(lchip, hw_tcam_mem)/ACL_IGS_BLOCK_MAX_NUM;
    if(CTC_EGRESS == p_replace->dir)
    {
        hw_ad_tbl = DsAcl0Egress_t;
        hw_key_tbl = DsEgrProgrammingAclTcam0_t;
        hw_tcam_mem = ProgramEgrAclTcamMem_t;
        entry_num = DRV_TABLE_MAX_INDEX(lchip, hw_tcam_mem)/ACL_EGS_BLOCK_MAX_NUM;
    }

    sal_memset(&dma_rw, 0, sizeof(dma_rw));
    SYS_ACL_PART_LOOP(part, merge_size)
    {
        src_table = hw_ad_tbl + p_replace->src_lkup_level + part;
        dest_table = hw_ad_tbl + p_replace->dest_lkup_level + part;
        for(loop=0; loop < DRV_TABLE_MAX_INDEX(lchip, hw_ad_tbl)/SYS_USW_ACL_DMA_OP_SIZE; loop++)
        {
            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, src_table, loop*SYS_USW_ACL_DMA_OP_SIZE, &cfg_addr);

            dma_rw.tbl_addr = cfg_addr;
            dma_rw.entry_num = SYS_USW_ACL_DMA_OP_SIZE;
            dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip, hw_ad_tbl);
            dma_rw.buffer = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf;
            dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, hw_ad_tbl);
            dma_rw.user_dma_mode = 1;
            MCHIP_DMA(lchip)->dma_read_table(lchip, &dma_rw);

            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE, &cfg_addr);
            dma_rw.tbl_addr = cfg_addr;
            MCHIP_DMA(lchip)->dma_write_table(lchip, &dma_rw);
        }

        src_table = hw_tcam_mem;
        dest_table = hw_tcam_mem;
        for(loop=0; loop < DRV_TABLE_MAX_INDEX(lchip, hw_key_tbl)/SYS_USW_ACL_DMA_OP_SIZE; loop++)
        {
            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, src_table, loop*SYS_USW_ACL_DMA_OP_SIZE+entry_num*(p_replace->src_lkup_level + part), &cfg_addr);

            dma_rw.tbl_addr = cfg_addr;
            dma_rw.entry_num = SYS_USW_ACL_DMA_OP_SIZE;
            dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip, hw_tcam_mem);
            dma_rw.buffer = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf;
            dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem);
            dma_rw.user_dma_mode = 1;
            MCHIP_DMA(lchip)->dma_read_table(lchip, &dma_rw);

            loop1=0;
            do
            {
                p_data = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf+loop1*16;
                p_mask = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf+loop1*16+6;

                mask_tmp = (p_mask[0] ^ p_data[0]);
                p_data[0] = mask_tmp&p_data[0];
                p_mask[0] = mask_tmp;

                mask_tmp = (p_mask[1] ^ p_data[1]);
                p_data[1] = mask_tmp&p_data[1];
                p_mask[1] = mask_tmp;

                mask_tmp = (p_mask[2] ^ p_data[2]);
                p_data[2] = mask_tmp&p_data[2];
                p_mask[2] = mask_tmp;

                mask_tmp = (p_mask[3] ^ p_data[3]);
                p_data[3] = mask_tmp&p_data[3];
                p_mask[3] = mask_tmp;

                mask_tmp = (p_mask[4] ^ p_data[4]);
                p_data[4] = mask_tmp&p_data[4];
                p_mask[4] = mask_tmp;

                mask_tmp = (p_mask[5] ^ p_data[5]);
                p_data[5] = mask_tmp&p_data[5];
                p_mask[5] = mask_tmp;

                loop1++;
            }while(loop1 <SYS_USW_ACL_DMA_OP_SIZE);

            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE+entry_num*(p_replace->dest_lkup_level + part), &cfg_addr);

            dma_rw.tbl_addr = cfg_addr;
            MCHIP_DMA(lchip)->dma_write_table(lchip, &dma_rw);
        }

        /*mv data for tcam scan*/
        if (drv_ser_get_tcam_scan_enable(lchip))
        {
            uint32 src_mem_id = 0;
            uint32 dst_mem_id = 0;
            src_mem_id = SYS_USW_ACL_MAP_MEM2DESC((p_replace->src_lkup_level + part));
            dst_mem_id = SYS_USW_ACL_MAP_MEM2DESC((p_replace->dest_lkup_level + part));
            CTC_ERROR_RETURN(sys_usw_dma_copy_desc_data(lchip, SYS_DMA_TCAM_SCAN_CHAN_ID, src_mem_id, dst_mem_id));
        }
    }
    return 0;
}


int32
_sys_usw_acl_replace_dma_delete(uint8 lchip, ctc_acl_replace_t* p_replace, uint8 merge_size)
{
    uint8 part;
    uint8 loop;
    uint32 cfg_addr;
    sys_dma_tbl_rw_t dma_rw;
    uint32 dest_table;
    uint32 hw_key_tbl = DsProgrammingAclTcam0_t;
    uint32 hw_tcam_mem = DRV_FROM_AT(lchip) ? ProgramIngAclTcamMem_t : ProgramAclTcamMem_t;
    uint16 entry_num = 0;

    entry_num = DRV_TABLE_MAX_INDEX(lchip, hw_tcam_mem)/ACL_IGS_BLOCK_MAX_NUM;
    if(CTC_EGRESS == p_replace->dir)
    {
        hw_key_tbl = DsEgrProgrammingAclTcam0_t;
        hw_tcam_mem = ProgramEgrAclTcamMem_t;
        entry_num = DRV_TABLE_MAX_INDEX(lchip, hw_tcam_mem)/ACL_EGS_BLOCK_MAX_NUM;
    }

    sal_memset(&dma_rw, 0, sizeof(dma_rw));
    sal_memset(p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf, 0, SYS_USW_ACL_DMA_OP_SIZE*TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem));
    dma_rw.entry_num = SYS_USW_ACL_DMA_OP_SIZE;
    dma_rw.entry_len = DRV_TABLE_ENTRY_SIZE(lchip, hw_tcam_mem);
    dma_rw.buffer = p_usw_acl_master[SYS_PP_BASE(lchip)]->replace_block_dma_buf;
    dma_rw.entry_offset = TABLE_ENTRY_OFFSET(lchip, hw_tcam_mem);
    dma_rw.user_dma_mode = 1;
    SYS_ACL_PART_LOOP(part, merge_size)
    {
        dest_table = hw_tcam_mem;
        for(loop=0; loop < DRV_TABLE_MAX_INDEX(lchip,hw_key_tbl)/SYS_USW_ACL_DMA_OP_SIZE; loop++)
        {
            drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, dest_table, loop*SYS_USW_ACL_DMA_OP_SIZE+entry_num*(p_replace->src_lkup_level + part), &cfg_addr);

            dma_rw.tbl_addr = cfg_addr;
            MCHIP_DMA(lchip)->dma_write_table(lchip, &dma_rw);
        }
        /*clear data for tcam scan*/
        if (drv_ser_get_tcam_scan_enable(lchip))
        {
            uint32 src_mem_id = 0;
            src_mem_id = SYS_USW_ACL_MAP_MEM2DESC((p_replace->src_lkup_level +  part));
            CTC_ERROR_RETURN(sys_usw_dma_copy_desc_data(lchip, SYS_DMA_TCAM_SCAN_CHAN_ID, src_mem_id, src_mem_id));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_replace_io_copy(uint8 lchip, ctc_acl_replace_t* p_replace)
{
    ctc_slistnode_t* group_node;
    ctc_list_pointer_node_t* entry_node;
    sys_acl_block_t* p_hdr_block;
    sys_acl_group_t* pg;
    sys_acl_entry_t * pe;
    uint32  old_key_id;
    uint32  old_act_id;
    uint32  new_key_id;
    uint32  new_act_id;
    uint8   step;
    uint8   part_num = 0;
    uint8   key_size = 0;
    uint32  old_hw_index;
    sys_acl_buffer_t  tmp_buffer;
    uint8 block_base = CTC_INGRESS == p_replace->dir ? 0 : ACL_IGS_BLOCK_MAX_NUM;
    uint32 hw_key_tbl = CTC_INGRESS == p_replace->dir ? DsProgrammingAclTcam0_t : DsEgrProgrammingAclTcam0_t;
    uint8   global_pp_en = SYS_ACL_IS_GLOBAL_PP_EN_LKUP(lchip, p_replace->dir, p_replace->src_lkup_level);
    uint8 pp_id = lchip - SYS_PP_BASE(lchip);
    drv_ioctl_param_t src_ioctl_param;
    drv_ioctl_param_t dst_ioctl_param;

    sal_memset(&tmp_buffer, 0, sizeof(tmp_buffer));

    p_hdr_block = &SYS_ACL_BLOCK(lchip, p_usw_acl_master[lchip]->league[p_replace->src_lkup_level+block_base].hdr_block_id);
    CTC_SLIST_LOOP(p_hdr_block->group_list, group_node)
    {
        pg = _ctc_container_of(group_node, sys_acl_group_t, head);
        CTC_LIST_POINTER_LOOP(entry_node ,&(pg->entry_list))
        {
            pe = _ctc_container_of(entry_node, sys_acl_entry_t, head);


            if (pe->ua != NULL && !pe->ua_type)
            {
                continue;
            }
            key_size = _sys_usw_acl_get_key_size(lchip, 1, pe, &step);
            SYS_ACL_GET_TBL_FUNC(lchip, pe, &old_key_id, &old_act_id, &old_hw_index);

            if( (old_key_id - hw_key_tbl) < p_replace->src_lkup_level
                || (old_key_id - hw_key_tbl) >= (p_replace->src_lkup_level + p_hdr_block->fpab.part_num) )
            {
                continue;
            }
            new_key_id = old_key_id + p_replace->dest_lkup_level - p_replace->src_lkup_level;
            new_act_id = old_act_id + p_replace->dest_lkup_level - p_replace->src_lkup_level;

            SYS_ACL_KEY_SIZE_TO_PART_NUM(key_size, part_num);

            /* move key and ad */
            src_ioctl_param.entry_len = part_num;
            src_ioctl_param.index = (DRV_IS_TMM(lchip) && CTC_EGRESS == pe->group->group_info.dir) ?old_hw_index/2 : old_hw_index;
            src_ioctl_param.op_bmp = (MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL) && !global_pp_en) ? (((1<<(pp_id/PP_NUM_PER_CORE)) << 6) | ((1<<(pp_id%PP_NUM_PER_CORE)) << 2)) : 0xfc;
            src_ioctl_param.p_value = NULL;
            src_ioctl_param.tbl_id = old_key_id;
            src_ioctl_param.ad_index = SYS_ACL_MAP_DRV_AD_INDEX(old_hw_index, step);
            src_ioctl_param.ad_tbl_id = old_act_id;
            
            dst_ioctl_param.entry_len = part_num;
            dst_ioctl_param.index = (DRV_IS_TMM(lchip) && CTC_EGRESS == pe->group->group_info.dir) ?old_hw_index/2 : old_hw_index;
            dst_ioctl_param.op_bmp = (MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL) && !global_pp_en) ? (((1<<(pp_id/PP_NUM_PER_CORE)) << 6) | ((1<<(pp_id%PP_NUM_PER_CORE)) << 2)) : 0xfc;
            dst_ioctl_param.p_value = NULL;
            dst_ioctl_param.tbl_id = new_key_id;
            dst_ioctl_param.ad_index = SYS_ACL_MAP_DRV_AD_INDEX(old_hw_index, step);
            dst_ioctl_param.ad_tbl_id = new_act_id;

            CTC_ERROR_RETURN(drv_ioctl_move_tcam(lchip, &src_ioctl_param, &dst_ioctl_param));
        }
    }
    return CTC_E_NONE;
}
int32
_sys_usw_acl_replace_io_delete(uint8 lchip, ctc_acl_replace_t* p_replace)
{
    ctc_slistnode_t* group_node;
    ctc_list_pointer_node_t* entry_node;
    sys_acl_block_t* p_hdr_block;
    sys_acl_group_t* pg;
    sys_acl_entry_t * pe;
    uint32  old_key_id;
    uint32  old_act_id;
    uint8   step;
    uint8   key_size = 0;
    uint32  old_hw_index;
    tbl_entry_t         tcam_key;
    sys_acl_buffer_t  tmp_buffer;
    uint8   global_pp_en = SYS_ACL_IS_GLOBAL_PP_EN_LKUP(lchip, p_replace->dir, p_replace->src_lkup_level);
    uint8 pp_id = lchip - SYS_PP_BASE(lchip);
    drv_ioctl_param_t p_ioctl_param;

    sal_memset(&tcam_key, 0, sizeof(tcam_key));
    sal_memset(&tmp_buffer, 0, sizeof(tmp_buffer));

    p_hdr_block = &SYS_ACL_BLOCK(lchip, p_usw_acl_master[lchip]->league[p_replace->dest_lkup_level].hdr_block_id);
    CTC_SLIST_LOOP(p_hdr_block->group_list, group_node)
    {
        pg = _ctc_container_of(group_node, sys_acl_group_t, head);
        CTC_LIST_POINTER_LOOP(entry_node,&(pg->entry_list))
        {
            pe = _ctc_container_of(entry_node, sys_acl_entry_t, head);
            if (pe->ua != NULL && !pe->ua_type)
            {
                continue;
            }
            key_size = _sys_usw_acl_get_key_size(lchip, 1, pe, &step);
            SYS_ACL_GET_TBL_FUNC(lchip, pe, &old_key_id, &old_act_id, &old_hw_index);
            if( (old_key_id - DsProgrammingAclTcam0_t) < p_replace->dest_lkup_level
                || (old_key_id - DsProgrammingAclTcam0_t) >= p_replace->dest_lkup_level + p_hdr_block->fpab.part_num)
            {
                continue;
            }
            old_key_id = old_key_id + p_replace->src_lkup_level - p_replace->dest_lkup_level;

            SYS_ACL_KEY_SIZE_TO_PART_NUM(key_size, p_ioctl_param.entry_len);

            p_ioctl_param.index = old_hw_index;
            p_ioctl_param.op_bmp = (MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL) && !global_pp_en) ? (((1<<(pp_id/PP_NUM_PER_CORE)) << 6) | ((1<<(pp_id%PP_NUM_PER_CORE)) << 2)) : 0xfc;
            p_ioctl_param.p_value = NULL;
            p_ioctl_param.tbl_id = old_key_id;

            CTC_ERROR_RETURN(drv_ioctl_remove_tcam(lchip, &p_ioctl_param));
        }
    }
    return CTC_E_NONE;
}

#define _ACL_REORDER_
int32
_sys_usw_acl_reorder_entry_scatter(uint8 lchip, sys_acl_league_t* p_sys_league)
{
    uint16 start_offset_160 = 0;
    uint16 start_offset_320 = 0;
    uint16 start_offset_640 = 0;
    uint16 cur_width_160 = 0;
    uint16 cur_width_320 = 0;
    uint16 cur_width_640 = 0;
    int32 shift_160 = 0;
    int32 shift_320 = 0;
    int32 shift_640 = 0;
    int32 vary = 0;
    int32 vary_160 = 0;
    int32 vary_320 = 0;
    int32 vary_640 = 0;
    ctc_fpa_block_t* old_fpab = NULL;
    sys_acl_block_t * pb = NULL;
    ctc_fpa_block_info_t block_info;
    sys_acl_fpa_ecnt_t fpa_ecnt;

    SYS_ACL_DBG_FUNC();

    pb = &(p_usw_acl_master[lchip]->block[p_sys_league->block_id]);

    old_fpab = &pb->fpab;

    if (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] != old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80])
    {
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_160]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_160]  = 0;

        old_fpab->start_offset[CTC_FPA_KEY_SIZE_320]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_320]  = 0;

        old_fpab->start_offset[CTC_FPA_KEY_SIZE_640]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_640]  = 0;

        vary = (int32)old_fpab->entry_count - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80];
        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_80, 0, vary, 0);
        fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] += vary;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80] += vary;
    }
    else
    {
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_80] = 0;

        sys_usw_acl_split_fpa_block(lchip, old_fpab->entry_count, fpa_ecnt);
        start_offset_160 = 0;
        start_offset_320 = start_offset_160 + fpa_ecnt[CTC_FPA_KEY_SIZE_160];
        start_offset_640 = start_offset_320 + fpa_ecnt[CTC_FPA_KEY_SIZE_320];

        cur_width_160 = (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] - old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160])*2;
        cur_width_320 = (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] - old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320])*4;
        cur_width_640 = (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] - old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640])*8;

        /*scatter default 160 size not enough, move 320 down*/
        if ((start_offset_320 - start_offset_160) < cur_width_160)
        {
            start_offset_320 = (start_offset_160 + cur_width_160);
            if (start_offset_320 % 4)
            {
                start_offset_320 += (4 - (start_offset_320 % 4));
            }
        }
        /*scatter default 320 size not enough, move 640 down*/
        if ((start_offset_640 - start_offset_320) < cur_width_320)
        {
            start_offset_640 = (start_offset_320 + cur_width_320);
            if (start_offset_640 % 8)
            {
                start_offset_640 += (8 - (start_offset_640 % 8));
            }
        }
        /*scatter default 640 size not enough, move up*/
        if ((old_fpab->entry_count - start_offset_640) < cur_width_640)
        {
            start_offset_640 = (old_fpab->entry_count - cur_width_640);
        }
        /*scatter default 320 size not enough, move up*/
        if ((start_offset_640 - start_offset_320) < cur_width_320)
        {
            start_offset_320 = (start_offset_640 - cur_width_320);
        }

        vary_160 = (int32)(start_offset_320 - start_offset_160)/2 - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160];
        vary_320 = (int32)(start_offset_640 - start_offset_320)/4 - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320];
        vary_640 = (int32)(old_fpab->entry_count - start_offset_640)/8 - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640];

        shift_160 = (int32)start_offset_160 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_160];
        shift_320 = (int32)start_offset_320 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_320];
        shift_640 = (int32)start_offset_640 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_640];

        if ((shift_320 < 0) && (shift_640 >= 0))
        {
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_160, shift_160, vary_160, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_160] = start_offset_160;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] += vary_160;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160] += vary_160;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_640, shift_640, vary_640, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_640] = start_offset_640;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] += vary_640;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640] += vary_640;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_320, shift_320, vary_320, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_320] = start_offset_320;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] += vary_320;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320] += vary_320;
        }
        else if ((shift_320 < 0) && (shift_640 < 0))
        {
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_160, shift_160, vary_160, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_160] = start_offset_160;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] += vary_160;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160] += vary_160;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_320, shift_320, vary_320, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_320] = start_offset_320;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] += vary_320;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320] += vary_320;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_640, shift_640, vary_640, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_640] = start_offset_640;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] += vary_640;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640] += vary_640;
        }
        else if ((shift_320 >= 0) && (shift_640 >= 0))
        {
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_640, shift_640, vary_640, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_640] = start_offset_640;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] += vary_640;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640] += vary_640;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_320, shift_320, vary_320, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_320] = start_offset_320;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] += vary_320;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320] += vary_320;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_160, shift_160, vary_160, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_160] = start_offset_160;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] += vary_160;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160] += vary_160;
        }
        else if ((shift_320 >= 0) && (shift_640 < 0))
        {
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_320, shift_320, vary_320, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_320] = start_offset_320;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] += vary_320;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320] += vary_320;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_160, shift_160, vary_160, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_160] = start_offset_160;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] += vary_160;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160] += vary_160;
            CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_640, shift_640, vary_640, 0);
            fpa_usw_scatter(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
            old_fpab->start_offset[CTC_FPA_KEY_SIZE_640] = start_offset_640;
            old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] += vary_640;
            old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640] += vary_640;
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_reorder_entry_down_to_up(uint8 lchip, sys_acl_league_t* p_sys_league)
{
    uint16 start_offset_160 = 0;
    uint16 start_offset_320 = 0;
    uint16 start_offset_640 = 0;
    int32 shift = 0;
    int32 vary = 0;
    int32 vary_160 = 0;
    int32 vary_320 = 0;
    int32 vary_640 = 0;
    ctc_fpa_block_t* old_fpab = NULL;
    sys_acl_block_t * pb = NULL;
    ctc_fpa_block_info_t block_info;

    SYS_ACL_DBG_FUNC();

    pb = &(p_usw_acl_master[lchip]->block[p_sys_league->block_id]);
    old_fpab = &pb->fpab;

    if (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] != old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80])
    {
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_160]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_160]  = 0;

        old_fpab->start_offset[CTC_FPA_KEY_SIZE_320]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_320]  = 0;

        old_fpab->start_offset[CTC_FPA_KEY_SIZE_640]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_640]  = 0;

        vary = (int32)old_fpab->entry_count - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80];
        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_80, 0, vary, 0);
        //fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_80, 0, vary);
        fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] += vary;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80] += vary;
    }
    else
    {
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_80] = 0;

        start_offset_640 = old_fpab->start_offset[CTC_FPA_KEY_SIZE_640] + (old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640]*8);
        shift = (int32)start_offset_640 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_640];
        vary_640 = (0 - (int32)old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640]);
        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_640, shift, vary_640, 0);
        //fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_640, shift, vary_640);
        fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_640] = start_offset_640;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] += vary_640;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640] += vary_640;

        start_offset_320 = start_offset_640 - (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] - old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320])*4;
        shift = (int32)start_offset_320 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_320];
        vary_320 = (0 - (int32)old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320]);
        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_320, shift, vary_320, 0);
        //fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_320, shift, vary_320);
        fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_320] = start_offset_320;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] += vary_320;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320] += vary_320;

        start_offset_160 = 0;
        shift = start_offset_160 - old_fpab->start_offset[CTC_FPA_KEY_SIZE_160];
        vary_160 = ((int32)start_offset_320/2 - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160]);
        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_160, shift, vary_160, 0);
        //fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_160, shift, vary_160);
        fpa_usw_increase(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_160] = start_offset_160;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] += vary_160;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160] += vary_160;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_reorder_entry_up_to_down(uint8 lchip, sys_acl_league_t* p_sys_league)
{
    uint16 start_offset_160 = 0;
    uint16 start_offset_320 = 0;
    uint16 start_offset_640 = 0;
    int32 shift_160 = 0;
    int32 shift_320 = 0;
    int32 shift_640 = 0;
    int32 vary = 0;
    int32 vary_160 = 0;
    int32 vary_320 = 0;
    int32 vary_640 = 0;
    ctc_fpa_block_t* old_fpab = NULL;
    sys_acl_block_t * pb = NULL;
    ctc_fpa_block_info_t block_info;

    SYS_ACL_DBG_FUNC();

    pb = &(p_usw_acl_master[lchip]->block[p_sys_league->block_id]);
    old_fpab = &pb->fpab;

    if (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] != old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80])
    {
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_160]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_160]  = 0;

        old_fpab->start_offset[CTC_FPA_KEY_SIZE_320]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_320]  = 0;

        old_fpab->start_offset[CTC_FPA_KEY_SIZE_640]    = old_fpab->entry_count;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640]  = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_640]  = 0;

        vary = (int32)old_fpab->entry_count - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80];
        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_80, 0, vary, 0);
        //fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_80, 0, vary);
        fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] += vary;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80] += vary;
    }
    else
    {
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_80] = 0;
        old_fpab->sub_rsv_count[CTC_FPA_KEY_SIZE_80] = 0;

        start_offset_160 = 0;
        start_offset_320 = start_offset_160 + (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] - old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160])*2;
        if (start_offset_320 % 4)
        {
            start_offset_320 += (4 - (start_offset_320 % 4));
        }

        start_offset_640 = start_offset_320 + (old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] - old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320])*4;

        if (start_offset_640 % 8)
        {
            start_offset_640 += (8 - (start_offset_640 % 8));
        }

        vary_160 = (int32)(start_offset_320 - start_offset_160)/2 - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160];
        vary_320 = (int32)(start_offset_640 - start_offset_320)/4 - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320];
        vary_640 = (int32)(old_fpab->entry_count - start_offset_640)/8 - (int32)old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640];

        shift_160 = (int32)start_offset_160 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_160];
        shift_320 = (int32)start_offset_320 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_320];
        shift_640 = (int32)start_offset_640 - (int32)old_fpab->start_offset[CTC_FPA_KEY_SIZE_640];

        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_160, shift_160, vary_160, 0);
        //fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_160, shift_160, vary_160);
        fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_160] = start_offset_160;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_160] += vary_160;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_160] += vary_160;

        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_320, shift_320, vary_320, 0);
        //fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_320, shift_320, vary_320);
        fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_320] = start_offset_320;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_320] += vary_320;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_320] += vary_320;

        CTC_FPA_BUILD_BLOCK_INFO(block_info, CTC_FPA_KEY_SIZE_640, shift_640, vary_640, 0);
        //fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, CTC_FPA_KEY_SIZE_640, shift_640, vary_640);
        fpa_usw_decrease(p_usw_acl_master[lchip]->fpa, &pb->fpab, &block_info);
        old_fpab->start_offset[CTC_FPA_KEY_SIZE_640] = start_offset_640;
        old_fpab->sub_entry_count[CTC_FPA_KEY_SIZE_640] += vary_640;
        old_fpab->sub_free_count[CTC_FPA_KEY_SIZE_640] += vary_640;
    }

    return CTC_E_NONE;
}

#define _ACL_WARMBOOT_
int32
_sys_usw_acl_wb_mapping_group(sys_wb_acl_group_t* p_wb_acl_group, sys_acl_group_t* p_acl_group, uint8 is_sync)
{
    if (is_sync)
    {
        p_wb_acl_group->group_id = p_acl_group->group_id;

        p_wb_acl_group->type = p_acl_group->group_info.type;
        p_wb_acl_group->block_id = p_acl_group->group_info.block_id;

        p_wb_acl_group->dir = (p_acl_group->group_info.dir == CTC_INGRESS)? 0:1;
        p_wb_acl_group->bitmap_status = p_acl_group->group_info.bitmap_status;
        p_wb_acl_group->flag = p_acl_group->flag;
        p_wb_acl_group->aset_idx = p_acl_group->aset_id;
        
        sal_memcpy(&p_wb_acl_group->un, &p_acl_group->group_info.un, sizeof(p_acl_group->group_info.un));
    }
    else
    {
        p_acl_group->group_id = p_wb_acl_group->group_id;
        p_acl_group->group_info.type = p_wb_acl_group->type;
        p_acl_group->group_info.block_id = p_wb_acl_group->block_id;
        p_acl_group->group_info.dir = p_wb_acl_group->dir ? CTC_EGRESS : CTC_INGRESS;
        p_acl_group->group_info.bitmap_status = p_wb_acl_group->bitmap_status;
        p_acl_group->flag = p_wb_acl_group->flag;
        p_acl_group->aset_id = p_wb_acl_group->aset_idx;
        sal_memcpy(&p_acl_group->group_info.un, &p_wb_acl_group->un, sizeof(ctc_port_bitmap_t));

        ctc_list_pointer_init(&(p_acl_group->entry_list));
        _sys_usw_acl_update_aset_ref(p_acl_group->lchip, p_acl_group->aset_id);
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_sync_group(void* bucket_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_acl_group_t* p_acl_group = NULL;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_wb_acl_group_t* p_wb_acl_group = NULL;

    p_acl_group = (sys_acl_group_t*)bucket_data;
    p_wb_data = (ctc_wb_data_t*)user_data;
    p_wb_acl_group = (sys_wb_acl_group_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_acl_group_t);

    _sys_usw_acl_wb_mapping_group(p_wb_acl_group, p_acl_group, 1);

    if(++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_mapping_udf(sys_wb_acl_udf_entry_t* p_wb_udf, sys_acl_udf_entry_t* p_udf, uint8 is_sync)
{
    if (is_sync)
    {
        /* buffer */
        p_wb_udf->udf_id = p_udf->udf_id;

        p_wb_udf->key_index = p_udf->key_index;
        p_wb_udf->is_sudf = p_udf->is_sudf;
        p_wb_udf->key_index_used = p_udf->key_index_used;
        p_wb_udf->ip_op = p_udf->ip_op;
        p_wb_udf->ip_frag = p_udf->ip_frag;
        p_wb_udf->mpls_num = p_udf->mpls_num;
        p_wb_udf->l4_type = p_udf->l4_type;
        p_wb_udf->udf_offset_num = p_udf->udf_offset_num;
        p_wb_udf->ip_protocol = p_udf->ip_protocol;
        p_wb_udf->granularity = p_udf->granularity;
        p_wb_udf->offset_type_valid = p_udf->offset_type_valid;
        p_wb_udf->is_installed = p_udf->is_installed;
        p_wb_udf->udf_hit_index = p_udf->udf_hit_index;
        p_wb_udf->scl_key_valid = p_udf->scl_key_valid;
        p_wb_udf->scl_offset_num = p_udf->scl_offset_num;
        p_wb_udf->prio = p_udf->fpae.priority;
    }
    else
    {
        p_udf->udf_id = p_wb_udf->udf_id;

        p_udf->key_index = p_wb_udf->key_index;
        p_udf->is_sudf = p_wb_udf->is_sudf;
        p_udf->key_index_used = p_wb_udf->key_index_used;
        p_udf->ip_op = p_wb_udf->ip_op;
        p_udf->ip_frag = p_wb_udf->ip_frag;
        p_udf->mpls_num = p_wb_udf->mpls_num;
        p_udf->l4_type = p_wb_udf->l4_type;
        p_udf->udf_offset_num = p_wb_udf->udf_offset_num;
        p_udf->ip_protocol = p_wb_udf->ip_protocol;
        p_udf->granularity = p_wb_udf->granularity;
        p_udf->offset_type_valid = p_wb_udf->offset_type_valid;
        p_udf->is_installed = p_wb_udf->is_installed;
        p_udf->udf_hit_index = p_wb_udf->udf_hit_index;
        p_udf->scl_key_valid = p_wb_udf->scl_key_valid;
        p_udf->scl_offset_num = p_wb_udf->scl_offset_num;
        p_udf->fpae.priority = p_wb_udf->prio;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_sync_udf_entry(void* bucket_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_acl_udf_entry_t* p_udf = NULL;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_wb_acl_udf_entry_t* p_wb_udf = NULL;

    p_udf = (sys_acl_udf_entry_t*)bucket_data;
    if (!p_udf->is_installed && !p_udf->is_sudf)
    {
        return CTC_E_NONE;
    }
    p_wb_data = (ctc_wb_data_t*)user_data;
    max_entry_cnt = p_wb_data->buffer_len / sizeof(sys_wb_acl_udf_entry_t);
    p_wb_udf = (sys_wb_acl_udf_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;

    _sys_usw_acl_wb_mapping_udf(p_wb_udf, p_udf, 1);

    if(++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_wb_vlan_build_tag_op(uint8 lchip,  uint8 in_op, uint8 in_mode, uint8* o_op)
{
    if (in_mode && (in_op==DRV_ENUM(DRV_VTAGACTIONTYPE_MODIFY)))
    {
        *o_op = CTC_ACL_VLAN_TAG_OP_REP_OR_ADD;
        return CTC_E_NONE;
    }

    if (in_op == DRV_ENUM(DRV_VTAGACTIONTYPE_NONE))
    {
        *o_op = CTC_ACL_VLAN_TAG_OP_NONE;
    }
    else if (in_op == DRV_ENUM(DRV_VTAGACTIONTYPE_MODIFY))
    {
        *o_op = CTC_ACL_VLAN_TAG_OP_REP;
    }
    else if (in_op == DRV_ENUM(DRV_VTAGACTIONTYPE_ADD))
    {
        *o_op = CTC_ACL_VLAN_TAG_OP_ADD;
    }
    else if (in_op == DRV_ENUM(DRV_VTAGACTIONTYPE_DELETE))
    {
        *o_op = CTC_ACL_VLAN_TAG_OP_DEL;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_wb_unbuild_vlan_edit_info(uint8 lchip, void* p_ds_edit, sys_acl_vlan_edit_t* p_vlan_edit)
{
    uint8 op = 0;
    uint8 mo = 0;
    uint8 o_op = 0;

    op = GetDsAclVlanActionProfile(V, sTagAction_f, p_ds_edit);
    mo = GetDsAclVlanActionProfile(V, stagModifyMode_f, p_ds_edit);
    _sys_usw_acl_wb_vlan_build_tag_op(lchip, op, mo, &o_op);
    p_vlan_edit->stag_op = o_op;

    op = GetDsAclVlanActionProfile(V, cTagAction_f, p_ds_edit);
    mo = GetDsAclVlanActionProfile(V, ctagModifyMode_f, p_ds_edit);
    _sys_usw_acl_wb_vlan_build_tag_op(lchip, op, mo, &o_op);
    p_vlan_edit->ctag_op = o_op;

    p_vlan_edit->svid_sl = GetDsAclVlanActionProfile(V, sVlanIdAction_f, p_ds_edit);
    p_vlan_edit->scos_sl = GetDsAclVlanActionProfile(V, sCosAction_f, p_ds_edit);
    p_vlan_edit->scfi_sl = GetDsAclVlanActionProfile(V, sCfiAction_f, p_ds_edit);

    p_vlan_edit->cvid_sl = GetDsAclVlanActionProfile(V, cVlanIdAction_f, p_ds_edit);
    p_vlan_edit->ccos_sl = GetDsAclVlanActionProfile(V, cCosAction_f, p_ds_edit);
    p_vlan_edit->ccfi_sl = GetDsAclVlanActionProfile(V, cCfiAction_f, p_ds_edit);
    p_vlan_edit->tpid_en = GetDsAclVlanActionProfile(V, svlanTpidIndexEn_f, p_ds_edit);
    p_vlan_edit->tpid_index = p_vlan_edit->tpid_en ? GetDsAclVlanActionProfile(V, svlanTpidIndex_f, p_ds_edit):0;

    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_mapping_hash_entry(uint8 lchip, sys_wb_acl_hash_entry_t* p_wb_acl_entry, sys_acl_hash_entry_t* p_acl_entry, uint8 is_sync)
{
    uint32 hw_index = 0;
    sys_acl_group_t* p_acl_group = NULL;
    uint32   key_id    = 0;
    uint32   act_id    = 0;
    //sys_acl_entry_t* pe_tcam = ACL_SHARE_PTR(p_acl_entry,sys_acl_entry_t);
    sys_acl_hash_action_t* pa_hash = NULL;
    sys_acl_entry_t* pe = (sys_acl_entry_t*) p_acl_entry;

    if(is_sync)
    {
        if(p_acl_entry->ua_type)
        {
            pa_hash = &p_acl_entry->ua->ad;
        }
        else
        {
            pa_hash = &p_acl_entry->ua->buffer.ad.hash;
        }
        p_wb_acl_entry->entry_id = p_acl_entry->entry_id;
        p_wb_acl_entry->group_id = p_acl_entry->group->group_id;

//        p_wb_acl_entry->aset_idx = p_acl_entry->aset_idx;
        p_wb_acl_entry->cos_index = pa_hash->cos_index;
        p_wb_acl_entry->igmp_snooping = p_acl_entry->igmp_snooping;
        p_wb_acl_entry->cid_mode = p_acl_entry->cid_mode;
        p_wb_acl_entry->bind_nh = p_acl_entry->bind_nh;
        p_wb_acl_entry->ldp_valid = pa_hash->ldp_valid;
        p_wb_acl_entry->sts_valid = pa_hash->stats_id ? 1 : 0;
        p_wb_acl_entry->policer_mode = pa_hash->policer_mode;
        p_wb_acl_entry->u1_type = p_acl_entry->u1_type;
        p_wb_acl_entry->hash_sel_tcp_flags = p_acl_entry->hash_sel_tcp_flags;

        p_wb_acl_entry->key_type = p_acl_entry->key_type;
        p_wb_acl_entry->hash_sel_id = p_acl_entry->hash_field_sel_id;
        p_wb_acl_entry->key_index = p_acl_entry->key_index;

        p_wb_acl_entry->is_install = p_acl_entry->installed;
        p_wb_acl_entry->hash_valid = p_acl_entry->hash_valid;
        p_wb_acl_entry->key_exist = p_acl_entry->key_exist;
        p_wb_acl_entry->key_conflict = p_acl_entry->key_conflict;
        p_wb_acl_entry->l4_type = p_acl_entry->l4_type;
        p_wb_acl_entry->mac_key_vlan_mode = p_acl_entry->mac_key_vlan_mode;
        p_wb_acl_entry->cpu_reason_id = pa_hash->cpu_reason_id;

        p_wb_acl_entry->nexthop_id = pa_hash->nexthop_id;
        p_wb_acl_entry->aset_id = p_acl_entry->aset_id;
    }
    else
    {
        //sys_acl_hash_action_t* p_hash_action = NULL;
        uint8   sys_key_type = 0;
        uint8   is_xflow = 0;
        uint32 stats_ptr = 0;
        sys_acl_buffer_t* p_buffer = &p_acl_entry->ua->buffer;
        sys_acl_flex_hash_t* fk = NULL;

        pa_hash = &p_acl_entry->ua->buffer.ad.hash;
        CTC_ERROR_RETURN(_sys_usw_acl_get_group_by_gid(lchip, p_wb_acl_entry->group_id, &p_acl_group));

        /*recover common db*/
        p_acl_entry->key_type = p_wb_acl_entry->key_type;
        p_acl_entry->action_type = SYS_ACL_ACTION_HASH_INGRESS;
        p_acl_entry->group = p_acl_group;
        p_acl_entry->key_index = p_wb_acl_entry->key_index;

        /*fpa*/
        p_acl_entry->entry_id = p_wb_acl_entry->entry_id;
        p_acl_entry->installed = p_wb_acl_entry->is_install;
        p_acl_entry->l4_type = p_wb_acl_entry->l4_type;
        p_acl_entry->hash_valid = p_wb_acl_entry->hash_valid;
        p_acl_entry->key_exist = p_wb_acl_entry->key_exist;
        p_acl_entry->key_conflict = p_wb_acl_entry->key_conflict;
        p_acl_entry->u1_type = p_wb_acl_entry->u1_type;
        pa_hash->cos_index = p_wb_acl_entry->cos_index;
        pa_hash->nexthop_id = p_wb_acl_entry->nexthop_id;
        pa_hash->policer_mode = p_wb_acl_entry->policer_mode;
        pa_hash->ldp_valid = p_wb_acl_entry->ldp_valid;
        pa_hash->cpu_reason_id = p_wb_acl_entry->cpu_reason_id;
        p_acl_entry->bind_nh = p_wb_acl_entry->bind_nh;
        p_acl_entry->mac_key_vlan_mode = p_wb_acl_entry->mac_key_vlan_mode;

        p_acl_entry->hash_sel_tcp_flags = p_wb_acl_entry->hash_sel_tcp_flags;
        p_acl_entry->hash_field_sel_id = p_wb_acl_entry->hash_sel_id;
        p_acl_entry->aset_id = p_wb_acl_entry->aset_id;

        is_xflow = SYS_ACL_KEY_IS_FLEX(pe->key_type) && p_acl_group->group_info.block_id > 0;
        if(SYS_ACL_KEY_IS_FLEX(pe->key_type))
        {
            fk = MCHIP_ACL(lchip)->get_flex_key(lchip, p_acl_group->group_info.dir, p_acl_entry->key_type);
            if(!fk)
            {
                CTC_ERROR_RETURN(CTC_E_NOT_EXIST);
            }
            p_buffer->fk = (sys_acl_flex_key_t*)fk;
        }
        SYS_ACL_GET_TBL_FUNC(lchip, pe, &key_id, &act_id, &hw_index);
        if(FALSE == p_acl_entry->installed)
        {
            ds_t pu32;
            drv_acc_in_t in;
            drv_acc_out_t out;
            sal_memset(&pu32, 0, sizeof(pu32));
            sal_memset(&in, 0, sizeof(in));
            sal_memset(&out, 0, sizeof(out));

            drv_set_warmboot_status(lchip, DRV_WB_STATUS_DONE);
            in.type     = DRV_ACC_TYPE_ADD;
            in.op_type  = DRV_ACC_OP_BY_INDEX;
            in.tbl_id   = key_id;
            in.data     = &pu32;
            in.index    = hw_index;
            in.module = is_xflow ? DRV_ACC_HASH_MODULE_X_FLOW : DRV_ACC_HASH_MODULE_FLOW;
            in.level = is_xflow ? p_acl_group->group_info.block_id : 0;
            in.oper_bmp = DRV_ACC_BMP_EN(MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL));
            CTC_ERROR_RETURN(drv_acc_api(lchip, &in, &out));
            drv_set_warmboot_status(lchip, DRV_WB_STATUS_RELOADING);
            return CTC_E_NONE;
        }

        _sys_usw_acl_update_aset_ref(lchip, p_acl_entry->aset_id);
        /*recover hash ad spool*/
        _sys_usw_acl_read_from_hw(lchip, key_id, act_id, hw_index, (void*)p_acl_entry);

        if(is_xflow)
        {
            pa_hash = mem_malloc(MEM_ACL_MODULE,CTC_OFFSET_OF(sys_acl_hash_action_t,calc_key_len));
            if(!pa_hash)
            {
                return CTC_E_NO_MEMORY;
            }
            sal_memcpy(pa_hash, &pe->ua->buffer.ad, CTC_OFFSET_OF(sys_acl_hash_action_t,calc_key_len));
        }
        else
        {
            uint8 key_type = 0;

            pa_hash->ds = p_buffer->action;
            pa_hash->lchip = lchip;
            CTC_ERROR_RETURN(ctc_spool_add(p_usw_acl_master[lchip]->ad_spool, pa_hash, NULL, &pa_hash));

            key_type = SYS_ACL_KEY_IS_FLEX(pe->key_type) ? fk->origin_key_type : pe->key_type;
            CTC_ERROR_RETURN(sys_usw_acl_map_ctc_to_sys_hash_key_type(key_type,&sys_key_type));
            p_usw_acl_master[lchip]->hash_sel_profile_count[sys_key_type][p_acl_entry->hash_field_sel_id]++;
            _sys_usw_acl_update_key_count(lchip, (void*)p_acl_entry, 1);

            stats_ptr = GetDsFlow(V, statsPtr_f, p_buffer->action);
            if(stats_ptr)
            {
                sys_usw_flow_stats_lookup_statsid(lchip, CTC_STATS_STATSID_TYPE_FLOW_HASH, stats_ptr, &pa_hash->stats_id, 0);
            }
        }

        if(SYS_ACL_KEY_IS_FLEX(pe->key_type))
        {
            fk->entry_count[p_acl_group->group_info.block_id]++;
        }

        /*if (p_acl_entry->aset_idx >= SYS_ACL_ASET_DEF_NUM && p_acl_entry->aset_idx != p_acl_group->aset_idx)
        {
            CTC_ERROR_RETURN(_sys_usw_acl_wb_restore_aset(p_acl_group->lchip, p_acl_group->aset_idx));
        }*/
        if (p_acl_entry->bind_nh)
        {
            _sys_usw_acl_bind_nexthop(lchip, (sys_acl_entry_t*)p_acl_entry, pa_hash->nexthop_id, 1);
        }
        /* add to group */
        ctc_list_pointer_insert_head(&(p_acl_group->entry_list), &(p_acl_entry->head));
        (p_acl_group->entry_count)++;

        p_acl_entry->ua = (void*)pa_hash;
        p_acl_entry->ua_type = 1;

    }
    return CTC_E_NONE;
}

void
_sys_usw_acl_restore_by_hw(uint8 lchip, uint32 key_id, uint32 act_id, sys_acl_entry_t* pe, sys_wb_acl_tcam_entry_t* pe_wb)
{
    sys_acl_buffer_t* p_buffer = NULL;
    sys_acl_tcam_action_t* pa_tcam;

    if(pe->ua == NULL || pe->ua_type)
    {
        return;
    }
    p_buffer = &pe->ua->buffer;
    pa_tcam = &p_buffer->ad.tcam;

#if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
    /* restore key field */
    if (SYS_ACL_GROUP_IS_PRESEL(pe->group))
    {
        uint32 key_width = 0;
        uint32 value = 0;
        uint32 mask = 0;
        uint16 offset= 0;
        if(pe_wb->range_valid)
        {
            uint32 qid_arr[] = {CTC_FIELD_KEY_SVLAN_RANGE, CTC_FIELD_KEY_CVLAN_RANGE,
                            CTC_FIELD_KEY_IP_PKT_LEN_RANGE, CTC_FIELD_KEY_L4_SRC_PORT_RANGE, CTC_FIELD_KEY_L4_DST_PORT_RANGE,
                            CTC_FIELD_KEY_SUDF_RANGE, CTC_FIELD_KEY_UDF_RANGE};
            uint8 i = 0;
            uint8 qid_num = sizeof(qid_arr)/sizeof(uint32);
            for( i = 0; i < qid_num; i++)
            {
                _sys_tmm_acl_get_key_field(lchip, qid_arr[i], pe, &key_width, &value, &mask, &offset);
                pe->un.g4.range_bitmap |= value & 0xffff;
            }
        }
        if(pe_wb->ceth_valid)
        {
            _sys_tmm_acl_get_key_field(lchip, CTC_FIELD_KEY_ETHER_TYPE, pe, &key_width, &value, &mask, &offset);
            pe->un.g4.ether_type_index = value & 0xff;
            pe->un.g4.ether_type_valid = 1;
        }
    }
    else
#endif
    {
        uint8 ceth_type = 0;
        uint16 range_bmp = 0;
        switch(pe->key_type)
        {
            case CTC_ACL_KEY_MAC:
                ceth_type = GetDsAclQosMacKey160(V, cEtherType_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_IPV6:
                range_bmp = GetDsAclQosIpv6Key320(V, rangeBitmap_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_IPV4_EXT:
                range_bmp = GetDsAclQosL3Key320(V, rangeBitmap_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_MAC_IPV4:
                range_bmp = GetDsAclQosMacL3Key320(V, rangeBitmap_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_MAC_IPV4_EXT:
                range_bmp = GetDsAclQosMacL3Key640(V, rangeBitmap_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_IPV6_EXT:
                range_bmp = GetDsAclQosIpv6Key640(V, rangeBitmap_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_MAC_IPV6:
                range_bmp = GetDsAclQosMacIpv6Key640(V, rangeBitmap_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_FWD_EXT:
                range_bmp = GetDsAclQosForwardKey640(V, rangeBitmap_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_COPP:
                ceth_type = GetDsAclQosCoppKey320(V, etherType_f, p_buffer->key);
                break;
            case CTC_ACL_KEY_COPP_EXT:
                range_bmp = GetDsAclQosCoppKey640(V, rangeBitmap_f, p_buffer->key);
                ceth_type = GetDsAclQosCoppKey640(V, etherType_f, p_buffer->key);
                break;
            default:
                break;
        }
        if(pe_wb->range_valid)
            pe->un.g4.range_bitmap = range_bmp ;
        if(pe_wb->ceth_valid)
        {
            pe->un.g4.ether_type_index = (ceth_type&0x3f);
            pe->un.g4.ether_type_valid = 1;
        }
    }

    /* restore action field */
    pa_tcam->vlan_edit->profile_id = GetDsAcl(V, vlanActionProfileId_f, p_buffer->action);
    if(pe_wb->ldp_valid && DRV_FROM_AT(lchip))
    {
        pa_tcam->ldp = GetDsAcl(V, u2_gI2eSrcCid_i2eSrcCid_f, p_buffer->action);
    }
    if(pe_wb->sts_valid)
    {
        uint32 stats_ptr = 0;
        uint8 sts_ram = 0;
        uint8 sts_type = CTC_STATS_STATSID_TYPE_ACL;
        uint8 dir = CTC_INGRESS;
        uint8 ptr_offset = MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM);
        if(pe->action_type == SYS_ACL_ACTION_TCAM_EGRESS)
        {
            stats_ptr = GetDsEpeAcl(V, statsPtr_f, p_buffer->action);
            sts_ram = GetDsEpeAcl(V, statsPoolNumber_f, p_buffer->action);
            stats_ptr |= (sts_ram << MCHIP_CAP(SYS_CAP_STATS_HW_LOCAL_STATSPTR_BIT_NUM));
            dir = CTC_EGRESS;
        }
        else if(SYS_AD_UNION_G_4 == pe->u2_type)
        {
            stats_ptr = GetDsAcl(V, u2_gStatsOp_statsPtr_f, p_buffer->action);
            sts_ram = GetDsAcl(V, u2_gStatsOp_statsPoolNumber_f, p_buffer->action);
            stats_ptr |= (sts_ram << ptr_offset);
        }
        else
        {
            uint16 stats_ptr1 = 0;
            uint16 stats_ptr2 = 0;

            /* statsptr */
            sts_ram =   GetDsAcl(V, u3_gCvlanAction_ccos_f, p_buffer->action);      //(stats_ptr)>>13 & 0x7;
            stats_ptr1 = GetDsAcl(V, u3_gCvlanAction_cvlanId_f, p_buffer->action);   //stats_ptr&0xFFF
            stats_ptr2 = GetDsAcl(V, u3_gCvlanAction_ccfi_f, p_buffer->action);      //(stats_ptr>>12)&0x1

            stats_ptr = ((uint32)(stats_ptr2&0x01)<<12) | (stats_ptr1 & 0xfff) | (sts_ram << ptr_offset);
            sts_type = CTC_STATS_STATSID_TYPE_NPM_IM;
        }

        sys_usw_flow_stats_lookup_statsid(lchip, sts_type, stats_ptr, &pa_tcam->stats_id, dir);
    }

    return;
}


int32
_sys_usw_acl_wb_mapping_entry(uint8 lchip, sys_wb_acl_tcam_entry_t* p_wb_acl_entry, sys_acl_entry_t* p_acl_entry, uint8 is_sync, void* p_range, ctc_list_pointer_t* node_list)
{
    uint8 block_id = 0;
    int32   local_block_index = 0;
    uint32 hw_index = 0;
    sys_acl_group_t* p_acl_group = NULL;
    sys_acl_block_t* p_acb = NULL;
    ctc_fpa_block_t* p_fpab_part = NULL;
    sys_acl_flex_key_t* fk = NULL;
    sys_acl_tcam_action_t* pa_tcam = &p_acl_entry->ua->buffer.ad.tcam;
    uint32   cmd = 0;
    uint32   key_id    = 0;
    uint32   act_id    = 0;
    uint32   nhid =0;
    ProgramAclRangeOpCtl_m* p_range_ctl = p_range;

    if(is_sync)
    {
        p_wb_acl_entry->nexthop_id = 0;
        p_wb_acl_entry->cpu_reason_id = 0;
        p_wb_acl_entry->ldp_valid = 0;
        p_wb_acl_entry->sts_valid = 0;
        p_wb_acl_entry->range_valid = 0;
        p_wb_acl_entry->ceth_valid = 0;
        p_wb_acl_entry->wlan_bmp = 0;

        p_wb_acl_entry->entry_id = p_acl_entry->fpae.entry_id;
        p_wb_acl_entry->priority = ACL_ENTRY_IS_TCAM(p_acl_entry) ? p_acl_entry->fpae.priority : ACL_SHARE_PTR(p_acl_entry, sys_acl_hash_entry_t)->priority;
        p_wb_acl_entry->group_id = p_acl_entry->group->group_id;
        p_wb_acl_entry->key_type = p_acl_entry->key_type;
        p_wb_acl_entry->is_install = p_acl_entry->fpae.flag;
        p_wb_acl_entry->offset_a = p_acl_entry->fpae.offset_a;

        if(p_acl_entry->ua && p_acl_entry->ua_type)
        {
            pa_tcam = &p_acl_entry->ua->ad;
            if (p_acl_entry->ad_type == SYS_ACL_AD_TYPE_DISABLE)
            {
                p_wb_acl_entry->nexthop_id = pa_tcam->nexthop_id;
                p_wb_acl_entry->cpu_reason_id = pa_tcam->cpu_reason_id;
                p_wb_acl_entry->ldp_valid = pa_tcam->ldp ? 1 : 0;
                p_wb_acl_entry->sts_valid = pa_tcam->stats_id ? 1 : 0;
            }
            p_wb_acl_entry->range_valid = p_acl_entry->un.g4.range_bitmap ? 1 : 0;
            p_wb_acl_entry->ceth_valid = p_acl_entry->un.g4.ether_type_valid ? 1 : 0;
            p_wb_acl_entry->wlan_bmp = p_acl_entry->un.g4.wlan_bmp;
        }
        else
        {
            p_wb_acl_entry->nexthop_id = p_acl_entry->un.nexthop_id;/* raw data,include all p_acl_entry->un */
        }

        p_wb_acl_entry->cos_index = p_acl_entry->cos_index;
        p_wb_acl_entry->macl3basic_key_cvlan_mode = p_acl_entry->macl3basic_key_cvlan_mode;
        p_wb_acl_entry->macl3basic_key_macda_mode = p_acl_entry->macl3basic_key_macda_mode;
        p_wb_acl_entry->igmp_snooping = p_acl_entry->igmp_snooping;
        p_wb_acl_entry->l2_type = p_acl_entry->l2_type;
        p_wb_acl_entry->l3_type = p_acl_entry->l3_type;
        p_wb_acl_entry->l4_type = p_acl_entry->l4_type;
        p_wb_acl_entry->l4_user_type = p_acl_entry->l4_user_type;
        p_wb_acl_entry->key_port_mode = p_acl_entry->key_port_mode;
        p_wb_acl_entry->fwd_key_nsh_mode = p_acl_entry->fwd_key_nsh_mode;
        p_wb_acl_entry->key_l4_port_mode = p_acl_entry->key_l4_port_mode;
        p_wb_acl_entry->mac_key_vlan_mode = p_acl_entry->mac_key_vlan_mode;
        p_wb_acl_entry->ip_dscp_mode = p_acl_entry->ip_dscp_mode;
        p_wb_acl_entry->key_mergedata_mode = p_acl_entry->key_mergedata_mode;
        p_wb_acl_entry->npm_union_bmp = p_acl_entry->npm_union_bmp;
        p_wb_acl_entry->bind_nh = p_acl_entry->bind_nh;
        p_wb_acl_entry->policer_mode = p_acl_entry->policer_mode;

        p_wb_acl_entry->u1_type = p_acl_entry->u1_type;
        p_wb_acl_entry->u2_type = p_acl_entry->u2_type;
        p_wb_acl_entry->u3_type = p_acl_entry->u3_type;
        p_wb_acl_entry->u4_type = p_acl_entry->u4_type;
        p_wb_acl_entry->u5_type = p_acl_entry->u5_type;

        p_wb_acl_entry->im_l_flag = p_acl_entry->im_l_flag;
        p_wb_acl_entry->im_d_flag = p_acl_entry->im_d_flag;
        p_wb_acl_entry->ad_type = p_acl_entry->ad_type;
        p_wb_acl_entry->aset_id = p_acl_entry->aset_id;
    }
    //TODO
    else
    {
        CTC_ERROR_RETURN(_sys_usw_acl_get_group_by_gid(lchip, p_wb_acl_entry->group_id, &p_acl_group));
        p_acl_entry->group = p_acl_group;
        p_acl_entry->key_type = p_wb_acl_entry->key_type;
        p_acl_entry->ad_type = p_wb_acl_entry->ad_type;

        /*fpa*/
        p_acl_entry->fpae.entry_id = p_wb_acl_entry->entry_id;
        p_acl_entry->fpae.priority = p_wb_acl_entry->priority;
        p_acl_entry->fpae.offset_a = p_wb_acl_entry->offset_a;
        p_acl_entry->fpae.flag = p_wb_acl_entry->is_install;
        /*p_acl_entry->fpae.step = p_wb_acl_entry->step;
        p_acl_entry->fpae.real_step = p_wb_acl_entry->step;*/

        if(p_acl_entry->ad_type == SYS_ACL_AD_TYPE_DISABLE)
        {
            pa_tcam->nexthop_id = p_wb_acl_entry->nexthop_id;
            pa_tcam->cpu_reason_id = p_wb_acl_entry->cpu_reason_id;
            p_acl_entry->un.g4.wlan_bmp = p_wb_acl_entry->wlan_bmp;
            nhid = p_wb_acl_entry->nexthop_id;
        }
        else
        {
            p_acl_entry->un.nexthop_id = p_wb_acl_entry->nexthop_id;
            nhid = (p_acl_entry->ad_type == SYS_ACL_AD_TYPE_REDIRECT) ? p_acl_entry->un.nexthop_id : 0;
        }

        p_acl_entry->l2_type = p_wb_acl_entry->l2_type;
        p_acl_entry->l3_type = p_wb_acl_entry->l3_type;
        p_acl_entry->l4_type = p_wb_acl_entry->l4_type;
        p_acl_entry->l4_user_type = p_wb_acl_entry->l4_user_type;
        p_acl_entry->key_port_mode = p_wb_acl_entry->key_port_mode;
        p_acl_entry->fwd_key_nsh_mode = p_wb_acl_entry->fwd_key_nsh_mode;
        p_acl_entry->key_l4_port_mode = p_wb_acl_entry->key_l4_port_mode;
        p_acl_entry->mac_key_vlan_mode = p_wb_acl_entry->mac_key_vlan_mode;
        p_acl_entry->ip_dscp_mode = p_wb_acl_entry->ip_dscp_mode;
        p_acl_entry->key_mergedata_mode = p_wb_acl_entry->key_mergedata_mode;
        p_acl_entry->cos_index = p_wb_acl_entry->cos_index;
        p_acl_entry->action_type = p_acl_group->group_info.dir ? SYS_ACL_ACTION_TCAM_EGRESS : SYS_ACL_ACTION_TCAM_INGRESS;

        p_acl_entry->igmp_snooping = p_wb_acl_entry->igmp_snooping;
        p_acl_entry->macl3basic_key_cvlan_mode = p_wb_acl_entry->macl3basic_key_cvlan_mode;
        p_acl_entry->macl3basic_key_macda_mode = p_wb_acl_entry->macl3basic_key_macda_mode;
        p_acl_entry->im_l_flag = p_wb_acl_entry->im_l_flag;
        p_acl_entry->im_d_flag = p_wb_acl_entry->im_d_flag;
        p_acl_entry->flag = p_wb_acl_entry->key_flag;
        p_acl_entry->npm_union_bmp = p_wb_acl_entry->npm_union_bmp;
        p_acl_entry->bind_nh = p_wb_acl_entry->bind_nh;
        p_acl_entry->policer_mode = p_wb_acl_entry->policer_mode;

        p_acl_entry->u1_type = p_wb_acl_entry->u1_type;
        p_acl_entry->u2_type = p_wb_acl_entry->u2_type;
        p_acl_entry->u3_type = p_wb_acl_entry->u3_type;
        p_acl_entry->u4_type = p_wb_acl_entry->u4_type;
        p_acl_entry->aset_id = p_wb_acl_entry->aset_id;

         if(p_acl_entry->fpae.flag == FPA_ENTRY_FLAG_UNINSTALLED)
        {
            if(ACL_ENTRY_IS_TCAM(p_acl_entry) && SYS_ACL_GROUP_IS_PRESEL(p_acl_group))
            {
                ctc_list_pointer_insert_head(node_list, &(p_acl_entry->head));
            }
            return CTC_E_NONE;
        }

        _sys_usw_acl_update_aset_ref(lchip, p_acl_entry->aset_id);
        if (SYS_ACL_GROUP_IS_PRESEL(p_acl_group))
        {
            fk = MCHIP_ACL(lchip)->get_flex_key(lchip, p_acl_group->group_info.dir, p_acl_entry->key_type);
            if(!fk)
            {
                CTC_ERROR_RETURN(CTC_E_NOT_EXIST);
            }
            p_acl_entry->fpae.key_size = fk->key_size;
        }
        else if (SYS_ACL_KEY_IS_FLEX(p_wb_acl_entry->key_type))
        {
            fk = ctc_vector_get(p_usw_acl_master[lchip]->fixed_key_vec, p_wb_acl_entry->key_type);
            if(!fk)
            {
                CTC_ERROR_RETURN(CTC_E_NOT_EXIST);
            }
        }
        p_acl_entry->ua->buffer.fk = fk;

        _sys_usw_acl_get_key_size(lchip, 1, p_acl_entry, &p_acl_entry->fpae.step);
        _sys_usw_acl_get_key_size(lchip, 0, p_acl_entry, &p_acl_entry->fpae.real_step);

        SYS_ACL_GET_TBL_FUNC(lchip, p_acl_entry, &key_id, &act_id, &hw_index);
        _sys_usw_acl_read_from_hw(lchip, key_id, act_id, hw_index, p_acl_entry);

        {
            uint8    step      = 0;
            uint8    part      = 0;
            uint8    key_size  = 0;
            uint32   vlan_edit_profile_id = 0;
            ds_t     vlan_action;
            sys_acl_vlan_edit_t   sys_vlan_edit;
            sys_acl_vlan_edit_t*   p_sys_vlan_edit_get = NULL;
            uint8 range_id;
            sys_acl_field_range_t* p_range_info = NULL;
            sys_parser_range_op_ctl_t range_ctl;

            pa_tcam->vlan_edit = &sys_vlan_edit;
            sal_memset(&sys_vlan_edit, 0, sizeof(sys_vlan_edit));
            _sys_usw_acl_restore_by_hw(lchip, key_id, act_id, p_acl_entry, p_wb_acl_entry);
            if (p_acl_entry->key_type != CTC_ACL_KEY_INTERFACE)
            {
                vlan_edit_profile_id = sys_vlan_edit.profile_id;
            }

            if(vlan_edit_profile_id != 0)
            {
                sal_memset(&sys_vlan_edit, 0, sizeof(sys_vlan_edit));
                sal_memset(&vlan_action, 0, sizeof(vlan_action));

                cmd = DRV_IOR(DsAclVlanActionProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, vlan_edit_profile_id, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &vlan_action));
                _sys_usw_acl_wb_unbuild_vlan_edit_info(lchip, &vlan_action, &sys_vlan_edit);
                sys_vlan_edit.profile_id = vlan_edit_profile_id;
                sys_vlan_edit.is_global = SYS_ACL_IS_GLOBAL_PP_EN_LKUP(lchip, p_acl_group->group_info.dir, p_acl_group->group_info.block_id);;
                CTC_ERROR_RETURN(ctc_spool_add(p_usw_acl_master[lchip]->vlan_edit_spool,
                                               &sys_vlan_edit, NULL, &p_sys_vlan_edit_get));
                pa_tcam->vlan_edit = p_sys_vlan_edit_get;
            }
            else
            {
                pa_tcam->vlan_edit = NULL;
            }

            if(SYS_ACL_GROUP_IS_PRESEL(p_acl_group) && (SYS_ACL_AD_TYPE_NONE == p_acl_entry->ad_type || SYS_ACL_AD_TYPE_DISABLE == p_acl_entry->ad_type) && p_acl_entry->un.g4.ether_type_valid != 0)
            {
                if (!CTC_ACL_KSET_ISSET(fk->kset, SYS_ACL_FIELD_FULL_ETHER_TYPE))
                {
                    uint8 global_pp_en = 0;
                    uint8  cether_type_index = p_acl_entry->un.g4.ether_type_index;
                    uint16 ether_type = sys_usw_acl_get_ether_type_by_index(lchip, p_acl_entry, cether_type_index);

                    global_pp_en = SYS_ACL_IS_GLOBAL_PP_EN_LKUP(lchip, p_acl_group->group_info.dir, p_acl_group->group_info.block_id);
                    CTC_ERROR_RETURN(MCHIP_ACL(lchip)->add_compress_ether_type(lchip, global_pp_en, p_acl_group->group_info.dir, ether_type, 0, NULL, &cether_type_index));
                    p_acl_entry->un.g4.ether_type_index = cether_type_index;
                    p_acl_entry->un.g4.ether_type_valid = 1;
                }
            }
            else if((SYS_ACL_AD_TYPE_NONE == p_acl_entry->ad_type || SYS_ACL_AD_TYPE_DISABLE == p_acl_entry->ad_type) && p_acl_entry->un.g4.ether_type_valid != 0)
            {
                uint8  cether_type_index = p_acl_entry->un.g4.ether_type_index;
                uint16 ether_type = sys_usw_acl_get_ether_type_by_index(lchip, p_acl_entry, cether_type_index);

                CTC_ERROR_RETURN(sys_usw_register_add_compress_ether_type(lchip, ether_type, 0, NULL, &cether_type_index));
                p_acl_entry->un.g4.ether_type_index = cether_type_index;
                p_acl_entry->un.g4.ether_type_valid = 1;
            }

            block_id = p_acl_group->group_info.block_id;
            if(CTC_EGRESS == p_acl_group->group_info.dir)
            {
                block_id += p_usw_acl_master[lchip]->igs_block_num;
            }
            p_acb = &SYS_ACL_BLOCK(lchip, block_id);
            key_size = _sys_usw_acl_get_key_size(lchip, 0, p_acl_entry, &step);
            if (p_acb->fpab.vblock && key_size == CTC_FPA_KEY_SIZE_160)
            {
                part = p_wb_acl_entry->offset_a / p_acb->fpab.entry_count;
                local_block_index = p_wb_acl_entry->offset_a - part*p_acb->fpab.entry_count;
                p_acb->fpab.vblock->entries[local_block_index+p_acb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_160]*part] = &(p_acl_entry->fpae);

                p_fpab_part = &p_acb[part].fpab;
                p_fpab_part->entries[local_block_index] = &(p_acl_entry->fpae);
                p_acb->fpab.vblock->free_count--;
                p_acb->fpab.vblock->sub_free_count[key_size]--;
                p_fpab_part->free_count--;
                p_fpab_part->sub_free_count[key_size]--;
            }
            else
            {
                p_acb->fpab.entries[p_wb_acl_entry->offset_a] = &(p_acl_entry->fpae);
                if (SYS_ACL_GROUP_IS_PRESEL(p_acl_group) && ACL_ENTRY_IS_TCAM(p_acl_entry))
                {
                    SYS_ACL_PART_LOOP(part, key_size)
                    {
                        p_acb[part].fpab.free_count -= step;
                        p_acb[part].fpab.sub_free_count[key_size]--;
                    }
                }
                else
                {
                    p_acb->fpab.free_count -= step;
                    p_acb->fpab.sub_free_count[key_size]--;
                }
            }

            /*restore range info*/
            if (SYS_ACL_GROUP_IS_PRESEL(p_acl_group) && 0 != p_acl_entry->un.g4.range_bitmap)
            {
                p_range_info = p_usw_acl_master[lchip]->field_range[1+p_acl_group->group_info.dir];
                step = ProgramAclRangeOpCtl_gRangeCheckCtl_1_fieldType_f - ProgramAclRangeOpCtl_gRangeCheckCtl_0_fieldType_f;
                p_range_ctl = &p_range_ctl[CTC_INGRESS == p_acl_group->group_info.dir? 1: 2];
                for(range_id = 0; range_id < p_range_info->entry_num; range_id++)
                {
                    if(CTC_IS_BIT_SET(p_acl_entry->un.g4.range_bitmap, range_id))
                    {
                        sal_memset(&range_ctl, 0, sizeof(range_ctl));
                        range_ctl.type = GetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_fieldType_f + step * range_id, p_range_ctl);
                        range_ctl.udf_index = GetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfIndex_f + step * range_id, p_range_ctl);
                        range_ctl.udf_sel = GetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfDataShift_f + step * range_id, p_range_ctl);
                        range_ctl.udf_mask = GetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfMask_f + step * range_id, p_range_ctl);
                        range_ctl.min_value = GetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_minValue_f + step * range_id, p_range_ctl);
                        range_ctl.max_value = GetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_maxValue_f + step * range_id, p_range_ctl);
                        range_ctl.is_sudf = !GetProgramAclRangeOpCtl(V, gRangeCheckCtl_0_udfDataSelect_f + step * range_id, p_range_ctl);

                        range_ctl.type = _sys_usw_acl_mapping_prg_range_type(range_ctl.type, range_ctl.is_sudf, 0);
                        CTC_ERROR_RETURN(_sys_usw_acl_add_range_bitmap(lchip, p_range_info, &range_ctl, &range_id));
                    }
                }
            }
            else if (0 != p_acl_entry->un.g4.range_bitmap)
            {
                step = ParserRangeOpCtl_array_1_maxValue_f - ParserRangeOpCtl_array_0_maxValue_f;
                p_range_info = p_usw_acl_master[lchip]->field_range[0];
                for(range_id = 0; range_id < p_range_info->entry_num; range_id++)
                {
                    if(CTC_IS_BIT_SET(p_acl_entry->un.g4.range_bitmap, range_id))
                    {
                        sal_memset(&range_ctl, 0, sizeof(range_ctl));
                        range_ctl.type = GetParserRangeOpCtl(V, array_0_opType_f + step * range_id, p_range_ctl);
                        range_ctl.min_value = GetParserRangeOpCtl(V, array_0_minValue_f + step * range_id, p_range_ctl);
                        range_ctl.max_value = GetParserRangeOpCtl(V, array_0_maxValue_f + step * range_id, p_range_ctl);
                        CTC_ERROR_RETURN(_sys_usw_acl_add_range_bitmap(lchip, p_range_info, &range_ctl, &range_id));
                    }
                }
            }
        }

        /* add to group */
        ctc_list_pointer_insert_head(&(p_acl_group->entry_list), &(p_acl_entry->head));
        (p_acl_group->entry_count)++;

        _sys_usw_acl_update_key_count(lchip, (void*)p_acl_entry, 1);
        if (SYS_ACL_GROUP_IS_PRESEL(p_acl_group))
        {
            fk->entry_count[p_acl_group->group_info.block_id]++;
        }
        else if (SYS_ACL_KEY_IS_FLEX(p_acl_entry->key_type))
        {
            ACL_SHARE_PTR(fk, sys_acl_fixed_key_t)->entry_count++;
        }

        if(nhid)
        {
            sys_acl_ldp_entry_t* pe_ldp = NULL;
            sys_nh_info_dsnh_t nhinfo;

            if (DRV_FROM_TMM(lchip))
            {   /*add nhid list*/
                sal_memset(&nhinfo, 0, sizeof(nhinfo));
                CTC_ERROR_DUMP(sys_usw_nh_get_nhinfo(lchip, nhid, &nhinfo, 0));
                //pe_ldp = sys_usw_acl_get_ldp_entry_by_eid(lchip, p_acl_entry->fpae.entry_id);
                if(SYS_NH_TYPE_OVERLAY == nhinfo.nh_entry_type || p_wb_acl_entry->ldp_valid
                  || (SYS_NH_TYPE_SRV6 == nhinfo.nh_entry_type))
                {
                    pe_ldp = mem_malloc(MEM_ACL_MODULE, sizeof(sys_acl_ldp_entry_t));
                    if (!pe_ldp)
                    {
                        return CTC_E_NO_MEMORY;
                    }
                    sal_memset(pe_ldp, 0, sizeof(sys_acl_ldp_entry_t));
                    pe_ldp->entry_id = p_wb_acl_entry->entry_id;
                    ctc_hash_insert(p_usw_acl_master[lchip]->ldp_entry, pe_ldp);
                    if(SYS_NH_TYPE_OVERLAY == nhinfo.nh_entry_type || (SYS_NH_TYPE_SRV6 == nhinfo.nh_entry_type))
                    {
                        sys_usw_add_ldp_node(lchip, p_usw_acl_master[lchip]->nhid_hash, nhid, &pe_ldp->nhid_list_node);
                    }
                }

                /*add ldp list*/
                 if(p_wb_acl_entry->ldp_valid && (nhinfo.logic_port || nhinfo.tunnel_id))
                {
                    pa_tcam->ldp = (SYS_NH_TYPE_SRV6 == nhinfo.nh_entry_type)?SYS_COM_LDP_SRH_ID(nhinfo.tunnel_id):nhinfo.logic_port;
                    sys_usw_add_ldp_node(lchip, p_usw_acl_master[lchip]->ldp_hash, pa_tcam->ldp, &pe_ldp->ldp_node);
                }
            }
            if (p_acl_entry->bind_nh)
            {
               _sys_usw_acl_bind_nexthop(lchip, p_acl_entry, nhid, 0);
            }
        }

        _sys_usw_acl_map_action_data(lchip, p_acl_entry, 1);
        if (SYS_ACL_AD_TYPE_DISABLE == p_acl_entry->ad_type)
        {
            p_acl_entry->ua = p_acl_entry->ua->buffer.pa;
            p_acl_entry->ua_type = 1;
        }
        else
        {
            p_acl_entry->ua = NULL;
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_sync_hash_entry(void* bucket_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    uint8 lchip = ((sys_acl_traverse_data_t*)user_data)->value0;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_acl_hash_entry_t* p_acl_entry = NULL;
    sys_wb_acl_hash_entry_t* p_wb_acl_entry = NULL;
    p_wb_data = (ctc_wb_data_t*)(((sys_acl_traverse_data_t*)user_data)->data0);
    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_acl_hash_entry_t);

    p_acl_entry = (sys_acl_hash_entry_t*)bucket_data;
    p_wb_acl_entry = (sys_wb_acl_hash_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;

    if(ACL_ENTRY_IS_TCAM(p_acl_entry) || p_acl_entry->hash_valid == 0)
    {
        return CTC_E_NONE;
    }

    _sys_usw_acl_wb_mapping_hash_entry(lchip, p_wb_acl_entry, p_acl_entry, 1);

    if (++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_sync_tcam_entry(void* bucket_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    uint8 lchip = ((sys_acl_traverse_data_t*)user_data)->value0;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_acl_entry_t* p_acl_entry = NULL;
    sys_wb_acl_tcam_entry_t* p_wb_acl_entry = NULL;
    p_wb_data = (ctc_wb_data_t*)(((sys_acl_traverse_data_t*)user_data)->data0);
    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_acl_tcam_entry_t);

    p_acl_entry = (sys_acl_entry_t*)bucket_data;
    p_wb_acl_entry = (sys_wb_acl_tcam_entry_t*)p_wb_data->buffer + p_wb_data->valid_cnt;

    if(!ACL_ENTRY_IS_TCAM(p_acl_entry))
    {
        return CTC_E_NONE;
    }
    if( p_acl_entry->fpae.flag == FPA_ENTRY_FLAG_UNINSTALLED && !SYS_ACL_GROUP_IS_PRESEL(p_acl_entry->group))
    {
        return CTC_E_NONE;
    }

    _sys_usw_acl_wb_mapping_entry(lchip, p_wb_acl_entry, p_acl_entry, 1, NULL, NULL);

    if (++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_mapping_flex_key(sys_wb_acl_flex_key_t* p_wb_acl_fk, void* p_acl_fk, uint8 is_sync, uint8 lchip)
{
    if (is_sync)
    {
        if(p_wb_acl_fk->is_flex_key)
        {
            sys_acl_flex_key_t* p_acl_flex = (sys_acl_flex_key_t*)p_acl_fk;
            if(SYS_ACL_FLEX_KEY_NODE_HASH == p_acl_flex->node_type)
            {
                sys_acl_flex_hash_t* p_hash_fk = (sys_acl_flex_hash_t*) p_acl_fk;
                p_wb_acl_fk->dir = CTC_INGRESS;
                p_wb_acl_fk->key_type = p_hash_fk->key_type;
                p_wb_acl_fk->node_type = p_hash_fk->node_type;
                p_wb_acl_fk->val.u_flow.hash_type = p_hash_fk->hash_type;
                p_wb_acl_fk->val.u_flow.origin_key_type = p_hash_fk->origin_key_type;
                p_wb_acl_fk->val.u_flow.mode = p_hash_fk->mode;
                p_wb_acl_fk->val.u_flow.key_size = p_hash_fk->key_size;
                p_wb_acl_fk->val.u_flow.udf_bmp = p_hash_fk->udf_bmp;
                sal_memcpy(&p_wb_acl_fk->kset, &p_hash_fk->kset, sizeof(p_hash_fk->kset));
            }
            else
            {
                p_wb_acl_fk->key_type = p_acl_flex->key_type;
                p_wb_acl_fk->val.u_flex.key_size = p_acl_flex->key_size;
                p_wb_acl_fk->val.u_flex.ltid_valid = p_acl_flex->ltid_valid;
                sal_memcpy(p_wb_acl_fk->val.u_flex.ltid, p_acl_flex->ltid, sizeof(p_wb_acl_fk->val.u_flex.ltid));
                p_wb_acl_fk->val.u_flex.flags = p_acl_flex->flags;
                p_wb_acl_fk->val.u_flex.lkup_type = p_acl_flex->lkup_type;
                sal_memcpy(&p_wb_acl_fk->kset, &p_acl_flex->kset, sizeof(p_acl_flex->kset));
                p_wb_acl_fk->dir = p_acl_flex->node_type == SYS_ACL_FLEX_KEY_NODE_E_TCAM ? CTC_EGRESS : CTC_INGRESS;
                p_wb_acl_fk->node_type = p_acl_flex->node_type;
                sal_memcpy(p_wb_acl_fk->val.u_flex.xdata_sel,p_acl_flex->xdata_sel, SYS_WB_ACL_XDATA_SEL_MAX_NUM*sizeof(uint8));
            }
        }
        else
        {
            sys_acl_fixed_key_t* p_acl_fixed = (sys_acl_fixed_key_t*) p_acl_fk;
            p_wb_acl_fk->key_type = p_acl_fixed->key_type;
            p_wb_acl_fk->val.u_fixed.origin_key_type = p_acl_fixed->origin_key_type;
            p_wb_acl_fk->val.u_fixed.eth_type = p_acl_fixed->eth_type;
            p_wb_acl_fk->val.u_fixed.l3_type = p_acl_fixed->l3_type;
            p_wb_acl_fk->val.u_fixed.l4_type = p_acl_fixed->l4_type;
            p_wb_acl_fk->val.u_fixed.l4_user_type = p_acl_fixed->l4_user_type;
            sal_memcpy(&p_wb_acl_fk->kset, &p_acl_fixed->kset, sizeof(p_acl_fixed->kset));
            p_wb_acl_fk->dir = p_acl_fixed->dir;
        }
    }
    else
    {
        if(p_wb_acl_fk->is_flex_key)
        {
#if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
          if(SYS_ACL_FLEX_KEY_NODE_HASH == p_wb_acl_fk->node_type)
          {
            sys_acl_flex_hash_t* p_hash_fk = (sys_acl_flex_hash_t*) p_acl_fk;
            p_hash_fk->key_type = p_wb_acl_fk->key_type;
            p_hash_fk->node_type = p_wb_acl_fk->node_type;
            p_hash_fk->hash_type = p_wb_acl_fk->val.u_flow.hash_type;
            p_hash_fk->origin_key_type = p_wb_acl_fk->val.u_flow.origin_key_type;
            p_hash_fk->mode = p_wb_acl_fk->val.u_flow.mode;
            p_hash_fk->key_size = p_wb_acl_fk->val.u_flow.key_size;
            p_hash_fk->udf_bmp = p_wb_acl_fk->val.u_flow.udf_bmp;
            sal_memcpy(&p_hash_fk->kset, &p_wb_acl_fk->kset, sizeof(p_hash_fk->kset));
          }
          else
          {
            uint8 loop = 0;
            uint8 ltid = 0;
            uint8 size_mode = 0;
            uint8 block_max = p_wb_acl_fk->dir == CTC_INGRESS ? ACL_IGS_BLOCK_MAX_NUM : ACL_EGS_BLOCK_MAX_NUM;
            uint8 port_bitmap = 0;

            sys_acl_flex_key_t* p_acl_flex = (sys_acl_flex_key_t*)p_acl_fk;
            p_acl_flex->key_type = p_wb_acl_fk->key_type;
            p_acl_flex->key_size = p_wb_acl_fk->val.u_flex.key_size;
            /*p_acl_flex->key_req_bits = p_wb_acl_fk->val.u_flex.key_req_bits;*/
            p_acl_flex->ltid_valid = p_wb_acl_fk->val.u_flex.ltid_valid;
            p_acl_flex->flags = p_wb_acl_fk->val.u_flex.flags;
            p_acl_flex->lkup_type = p_wb_acl_fk->val.u_flex.lkup_type;
            p_acl_flex->node_type = p_wb_acl_fk->node_type;
            sal_memcpy(&p_acl_flex->kset, &p_wb_acl_fk->kset, sizeof(p_acl_flex->kset));
            sal_memcpy(p_acl_flex->xdata_sel, p_wb_acl_fk->val.u_flex.xdata_sel, SYS_WB_ACL_XDATA_SEL_MAX_NUM*sizeof(uint8));
            if(SYS_ACL_KEY_IS_FLEX(p_wb_acl_fk->key_type))
            {
                sal_memcpy(p_acl_flex->ltid, p_wb_acl_fk->val.u_flex.ltid, sizeof(p_wb_acl_fk->val.u_flex.ltid));
            }
            else
            {
                _sys_tmm_acl_map_key_type_to_ltid(p_wb_acl_fk->key_type, &ltid);
                SYS_ACL_IGS_BLK_LOOP(loop, block_max)
                {
                    p_acl_flex->ltid[loop] = ltid;
                    CTC_BIT_SET(p_acl_flex->ltid_valid, loop);
                }
                p_acl_flex->ad_index = ltid;
            }
            switch(p_acl_flex->key_size)
            {
            case CTC_ACL_KEY_SIZE_160:
                size_mode = SYS_ACL_FK_SIZE_MODE_SINGLE;
                break;
            case CTC_ACL_KEY_SIZE_320:
                size_mode = SYS_ACL_FK_SIZE_MODE_DOUBLE;
                break;
            case CTC_ACL_KEY_SIZE_480:
                size_mode = SYS_ACL_FK_SIZE_MODE_TRIPLE;
                break;
            default:
                size_mode = SYS_ACL_FK_SIZE_MODE_AUTO;
                break;
            }
            if (CTC_ACL_KSET_ISSET(p_acl_flex->kset, CTC_FIELD_KEY_PORT_BITMAP))
            {
                CTC_ACL_KSET_REMOVE(p_acl_flex->kset, CTC_FIELD_KEY_PORT_BITMAP);
                port_bitmap = 1;
            }
            CTC_ERROR_RETURN(_sys_tmm_acl_build_extract_db(lchip, size_mode, p_acl_fk));
            if(port_bitmap)
            {
                CTC_ACL_KSET_ADD(p_acl_flex->kset, CTC_FIELD_KEY_PORT_BITMAP);
            }
          }
#endif
        }
        else
        {
            sys_acl_fixed_key_t* p_acl_fixed = (sys_acl_fixed_key_t*) p_acl_fk;
            p_acl_fixed->key_type = p_wb_acl_fk->key_type;
            p_acl_fixed->origin_key_type = p_wb_acl_fk->val.u_fixed.origin_key_type;
            p_acl_fixed->eth_type = p_wb_acl_fk->val.u_fixed.eth_type;
            p_acl_fixed->l3_type = p_wb_acl_fk->val.u_fixed.l3_type;
            p_acl_fixed->l4_type = p_wb_acl_fk->val.u_fixed.l4_type;
            p_acl_fixed->l4_user_type = p_wb_acl_fk->val.u_fixed.l4_user_type;
            p_acl_fixed->dir = p_wb_acl_fk->dir;
            sal_memcpy(&p_acl_fixed->kset, &p_wb_acl_fk->kset, sizeof(p_acl_fixed->kset));
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_wb_sync_flex_key(void* bucket_data, void* user_data)
{
    uint8  lchip = 0;
    uint32 max_entry_cnt = 0;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_wb_acl_flex_key_t* p_wb_acl_fk = NULL;
    p_wb_data = (ctc_wb_data_t*)(((sys_acl_traverse_data_t*)user_data)->data0);
    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_acl_flex_key_t);

    lchip = ((sys_acl_traverse_data_t*)user_data)->value0 & 0xff;

    p_wb_acl_fk = (sys_wb_acl_flex_key_t*)p_wb_data->buffer + p_wb_data->valid_cnt;
    p_wb_acl_fk->is_flex_key = ((sys_acl_traverse_data_t*)user_data)->value0 >> 8 ;

    _sys_usw_acl_wb_mapping_flex_key(p_wb_acl_fk, bucket_data, 1, lchip);

    if (++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
    return CTC_E_NONE;
}

void
_sys_usw_acl_wb_mapping_aset(uint8 lchip, sys_wb_acl_aset_t* p_wb_aset, sys_acl_aset_t* p_aset, uint8 is_sync)
{
    if(is_sync)
    {
        p_wb_aset->aset_id = p_aset->aset_id;
        p_wb_aset->type = p_aset->type;
        p_wb_aset->u1_type = p_aset->u1_type;
        p_wb_aset->u2_type = p_aset->u2_type;
        p_wb_aset->u3_type = p_aset->u3_type;
        p_wb_aset->u4_type = p_aset->u4_type;
        p_wb_aset->u5_type = p_aset->u5_type;
        p_wb_aset->is_static = p_aset->is_static;
        p_wb_aset->xdata_prof_id = p_aset->xdata_prof_id;
        sal_memcpy(p_wb_aset->w, p_aset->w, sizeof(p_wb_aset->w));
    }
    else
    {
        sys_usw_opf_t opf;
        uint8 pp_base = drv_vchip_get_pp_base(lchip);
        p_aset->aset_id = p_wb_aset->aset_id;
        p_aset->u1_type = p_wb_aset->u1_type;
        p_aset->u2_type = p_wb_aset->u2_type;
        p_aset->u3_type = p_wb_aset->u3_type;
        p_aset->u4_type = p_wb_aset->u4_type;
        p_aset->u5_type = p_wb_aset->u5_type;
        p_aset->type = p_wb_aset->type ;
        p_aset->is_static = p_wb_aset->is_static;
        p_aset->xdata_prof_id = p_wb_aset->xdata_prof_id;
        sal_memcpy(p_aset->w, p_wb_aset->w, sizeof(p_wb_aset->w));

        sal_memset(&opf, 0, sizeof(opf));
        opf.pool_type = p_usw_acl_master[pp_base]->opf_type_aset;
        if(p_aset->aset_id)
        {
            sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_aset->aset_id);
        }
    }
     return;
}

int32
_sys_usw_acl_wb_sync_aset(void* bucket_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    ctc_wb_data_t* p_wb_data = NULL;
    sys_wb_acl_aset_t* p_wb_aset = NULL;
    p_wb_data = (ctc_wb_data_t*)((sys_acl_traverse_data_t*)user_data);
    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_acl_aset_t);

    p_wb_aset = (sys_wb_acl_aset_t*)p_wb_data->buffer + p_wb_data->valid_cnt;

    if( SYS_ACL_ASET_IS_DEF(((sys_acl_aset_t *) bucket_data)->aset_id) )
    {
        return CTC_E_NONE;
    }
    _sys_usw_acl_wb_mapping_aset(0,p_wb_aset, bucket_data, 1);

    if (++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }
    return CTC_E_NONE;
}


#define _ACL_INIT_


/* just for arctic nsh!!! */
int32
sys_usw_acl_flow_hash_default_entry_init(uint8 lchip)
{
    uint16 lport = 0;
    uint32 offset = 0;
    uint32 cmd   = 0;
    uint32 entry_num = 0;
    sys_usw_opf_t opf;
    FlowHashLookupCtl_m ctl;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = p_usw_acl_master[lchip]->opf_type_ad;

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsFlow_t, &entry_num));
    offset = entry_num-1;
    for(lport = 0; lport < SYS_RSV_PORT_START; lport++)
    {
        if(sys_usw_chip_get_fwd_port_en(lchip, lport) == 0)
        {
            continue;
        }
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, offset-lport));
    }

    cmd = DRV_IOR(FlowHashLookupCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ctl));
    SetFlowHashLookupCtl(V, flowHashDefaultEntryEn_f, &ctl, 1);
    SetFlowHashLookupCtl(V, flowHashDefaultEntryBase_f, &ctl, entry_num-SYS_RSV_PORT_START);
    cmd = DRV_IOW(FlowHashLookupCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ctl));
    p_usw_acl_master[lchip]->default_base = entry_num-SYS_RSV_PORT_START;

    return CTC_E_NONE;
}

int32
_sys_usw_acl_build_flow_hash_default_entry(uint8 lchip, uint16 lport,uint8 is_add)
{
    uint32 cmd   = 0;
    ctc_acl_field_action_t action_field;
    sys_acl_hash_entry_t pe;
    sys_acl_buffer_t buffer;

    sal_memset(&action_field, 0, sizeof(ctc_acl_field_action_t));
    sal_memset(&pe, 0, sizeof(sys_acl_hash_entry_t));
    sal_memset(&buffer, 0, sizeof(sys_acl_buffer_t));

    pe.ua = (void*)&buffer;

    action_field.type = CTC_ACL_FIELD_ACTION_DISCARD;

    CTC_ERROR_RETURN(_sys_usw_acl_add_dsflow_field(lchip, &action_field, (sys_acl_hash_entry_t*)&pe, is_add));

    cmd = DRV_IOW(DsFlow_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_usw_acl_master[lchip]->default_base+lport, cmd, buffer.action));

    return CTC_E_NONE;
}

/* 10 combinations */
int32
_sys_usw_acl_create_rsv_group(uint8 lchip)
{
    ctc_acl_group_info_t hash_group;
    sal_memset(&hash_group, 0, sizeof(hash_group));

    hash_group.type = CTC_ACL_GROUP_TYPE_HASH;

    CTC_ERROR_RETURN(_sys_usw_acl_create_group(lchip, CTC_ACL_GROUP_ID_HASH_MAC, &hash_group));
    CTC_ERROR_RETURN(_sys_usw_acl_create_group(lchip, CTC_ACL_GROUP_ID_HASH_IPV4, &hash_group));
    CTC_ERROR_RETURN(_sys_usw_acl_create_group(lchip, CTC_ACL_GROUP_ID_HASH_IPV6, &hash_group));
    CTC_ERROR_RETURN(_sys_usw_acl_create_group(lchip, CTC_ACL_GROUP_ID_HASH_MPLS, &hash_group));
    CTC_ERROR_RETURN(_sys_usw_acl_create_group(lchip, CTC_ACL_GROUP_ID_HASH_L2_L3, &hash_group));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_init_vlan_edit_stag(uint8 lchip, sys_acl_vlan_edit_t* p_vlan_edit, uint16* p_prof_idx)
{
    uint8 stag_op = 0;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    for (stag_op = CTC_ACL_VLAN_TAG_OP_NONE; stag_op < CTC_ACL_VLAN_TAG_OP_MAX; stag_op++)
    {
        p_vlan_edit->stag_op = stag_op;

        switch (stag_op)
        {
        case CTC_ACL_VLAN_TAG_OP_REP:         /* template has no replace */
            continue;
        case CTC_ACL_VLAN_TAG_OP_REP_OR_ADD:  /* 4*/
        case CTC_ACL_VLAN_TAG_OP_ADD:         /* 4*/
        {
            p_vlan_edit->svid_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            p_vlan_edit->scos_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, p_vlan_edit, p_prof_idx));

            p_vlan_edit->svid_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            p_vlan_edit->scos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, p_vlan_edit, p_prof_idx));

            p_vlan_edit->svid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            p_vlan_edit->scos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, p_vlan_edit, p_prof_idx));

            p_vlan_edit->svid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            p_vlan_edit->scos_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, p_vlan_edit, p_prof_idx));
        }
        break;
        case CTC_ACL_VLAN_TAG_OP_NONE:      /*1*/
        case CTC_ACL_VLAN_TAG_OP_DEL:       /*1*/
            p_vlan_edit->svid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            p_vlan_edit->scos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, p_vlan_edit, p_prof_idx));
            break;
        }
    }

    return CTC_E_NONE;
}


int32
_sys_usw_acl_init_vlan_edit(uint8 lchip)
{
    uint16              prof_idx = 0;
    uint8               ctag_op  = 0;

    sys_acl_vlan_edit_t vlan_edit;
    sal_memset(&vlan_edit, 0, sizeof(vlan_edit));

    for (ctag_op = CTC_ACL_VLAN_TAG_OP_NONE; ctag_op < CTC_ACL_VLAN_TAG_OP_MAX; ctag_op++)
    {
        vlan_edit.ctag_op = ctag_op;

        switch (ctag_op)
        {
        case CTC_ACL_VLAN_TAG_OP_ADD:        /* template has no append ctag */
        case CTC_ACL_VLAN_TAG_OP_REP:        /* template has no replace */
            continue;
        case CTC_ACL_VLAN_TAG_OP_REP_OR_ADD: /* 4 */
        {
            vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            CTC_ERROR_RETURN(_sys_usw_acl_init_vlan_edit_stag(lchip, &vlan_edit, &prof_idx));

            vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            CTC_ERROR_RETURN(_sys_usw_acl_init_vlan_edit_stag(lchip, &vlan_edit, &prof_idx));

            vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            CTC_ERROR_RETURN(_sys_usw_acl_init_vlan_edit_stag(lchip, &vlan_edit, &prof_idx));

            vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_NEW;
            CTC_ERROR_RETURN(_sys_usw_acl_init_vlan_edit_stag(lchip, &vlan_edit, &prof_idx));
        }
        break;
        case CTC_ACL_VLAN_TAG_OP_NONE:    /* 1 */
        case CTC_ACL_VLAN_TAG_OP_DEL:     /* 1 */
            vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
            CTC_ERROR_RETURN(_sys_usw_acl_init_vlan_edit_stag(lchip, &vlan_edit, &prof_idx));
            break;
        }
    }
    /* 6 * 10 = 60 */

    /*for swap*/
    vlan_edit.ctag_op = CTC_ACL_VLAN_TAG_OP_REP_OR_ADD;
    vlan_edit.stag_op = CTC_ACL_VLAN_TAG_OP_REP_OR_ADD;

    vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.svid_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.scos_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, &vlan_edit, &prof_idx));

    vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
    vlan_edit.svid_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.scos_sl = CTC_ACL_VLAN_TAG_SL_NONE;
    CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, &vlan_edit, &prof_idx));

    vlan_edit.cvid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
    vlan_edit.ccos_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    vlan_edit.svid_sl = CTC_ACL_VLAN_TAG_SL_NONE;
    vlan_edit.scos_sl = CTC_ACL_VLAN_TAG_SL_ALTERNATIVE;
    CTC_ERROR_RETURN(_sys_usw_acl_install_vlan_edit(lchip, &vlan_edit, &prof_idx));

    /* 60+3 = 63 */
    return CTC_E_NONE;
}

/*
 * init acl register
 */
int32
_sys_usw_acl_init_global_cfg(uint8 lchip, ctc_acl_global_cfg_t* acl_global_cfg)
{
    sys_acl_register_t acl_register;
    CTC_PTR_VALID_CHECK(acl_global_cfg);

    sal_memset(&acl_register, 0, sizeof(acl_register));
    CTC_ERROR_RETURN(_sys_usw_acl_set_register(lchip, &acl_register));

    return CTC_E_NONE;
}

int32
_sys_usw_acl_ofb_init(uint8 lchip)
{
    uint32               entry_num    = 0;

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsCategoryIdPairTcamKey_t, &entry_num));
    if (entry_num)
    {
        sys_usw_ofb_param_t ofb;

        /*last index is used for a special entry*/
        entry_num = MCHIP_CAP(SYS_CAP_ACL_TCAM_CID_PAIR) - 1;    /*mark: !!!!!!!!*/

        sal_memset(&ofb, 0, sizeof(ofb));
        ofb.size = entry_num/2;
        ofb.ofb_cb = _sys_usw_acl_tcam_cid_move_cb;
        ofb.multiple = 1;

        CTC_ERROR_RETURN(sys_usw_ofb_init(lchip, 2, entry_num, &p_usw_acl_master[lchip]->ofb_type_cid));

        CTC_ERROR_RETURN(sys_usw_ofb_init_offset(lchip, p_usw_acl_master[lchip]->ofb_type_cid, 0, &ofb));
        ofb.size = entry_num - entry_num/2;
        CTC_ERROR_RETURN(sys_usw_ofb_init_offset(lchip, p_usw_acl_master[lchip]->ofb_type_cid, 1, &ofb));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_opf_init(uint8 lchip)
{
    uint32               entry_num    = 0;
    uint32               start_offset = 0;
    uint8                vedit_pool_num = (DRV_FROM_AT(lchip) && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL)) ? 2 : 1;
    sys_usw_opf_t opf;

    /*vlan-edit opf*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsAclVlanActionProfile_t, &entry_num));
    start_offset = SYS_ACL_VLAN_ACTION_RESERVE_NUM;
    entry_num   -= SYS_ACL_VLAN_ACTION_RESERVE_NUM;

    if (entry_num)
    {
        CTC_ERROR_RETURN(
        sys_usw_opf_init(lchip, &p_usw_acl_master[lchip]->opf_type_vlan_edit, vedit_pool_num , "opf-acl-vlan-action"));

        opf.pool_index = 0;
        opf.pool_type  = p_usw_acl_master[lchip]->opf_type_vlan_edit;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, entry_num/vedit_pool_num));
        if(DRV_FROM_AT(lchip) && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
        {
            opf.pool_index = 1;
            opf.pool_type  = p_usw_acl_master[lchip]->opf_type_vlan_edit;
            CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, entry_num/vedit_pool_num + 1, entry_num - (entry_num/vedit_pool_num)));
        }
    }

    /*hash-ad opf*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    entry_num = 0;
    start_offset = 0;

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsFlow_t, &entry_num));
    if (entry_num)
    {
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_acl_master[lchip]->opf_type_ad, MCHIP_CAP(SYS_CAP_LOCAL_SLICE_NUM) , "opf-acl-ad"));

        opf.pool_index = 0;
        opf.pool_type  = p_usw_acl_master[lchip]->opf_type_ad;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, entry_num));
    }

    /*category-id hash left/right ad opf*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    entry_num = 0;
    start_offset = 0;

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsCategoryIdPairHashLeftAd_t, &entry_num));
    if (entry_num)
    {
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_acl_master[lchip]->opf_type_cid_ad, 2, "opf-acl-cid-ad"));

        opf.pool_index = 0;
        opf.pool_type  = p_usw_acl_master[lchip]->opf_type_cid_ad;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, entry_num));
        opf.pool_index = 1;
        opf.pool_type  = p_usw_acl_master[lchip]->opf_type_cid_ad;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, start_offset, entry_num));
    }

    /*udf cam opf*/
    CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_acl_master[lchip]->opf_type_udf, 3, "opf-acl-type-udf"));
    opf.pool_type  = p_usw_acl_master[lchip]->opf_type_udf;

    opf.pool_index = SYS_USW_ACL_UDF_MAPPED_INDEX; /*udf map index*/

    CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, MCHIP_CAP(SYS_CAP_ACL_UDF_AD_ID_MIN), MCHIP_CAP(SYS_CAP_ACL_UDF_ENTRY_NUM)));

    if(DRV_FROM_AT(lchip))
    {
        start_offset = 513;
        entry_num = MCHIP_CAP(SYS_CAP_ACL_UDF_ENTRY_NUM) - 1;
    }
    else
    {
        start_offset = 512;
        entry_num = MCHIP_CAP(SYS_CAP_ACL_UDF_ENTRY_NUM);
    }
    opf.pool_index = SYS_USW_ACL_UDF_MAPPED_INDEX1; /*flow sudf map index*/
    CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, MCHIP_CAP(SYS_CAP_ACL_SUDF_AD_ID_MIN), MCHIP_CAP(SYS_CAP_ACL_SUDF_ENTRY_NUM)));

    opf.pool_index = SYS_USW_ACL_SUDF_AD_INDEX; /*flow sudf ad index*/
    CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, MCHIP_CAP(SYS_CAP_ACL_SUDF_AD_ID_MIN), MCHIP_CAP(SYS_CAP_ACL_SUDF_ENTRY_NUM)));

    if(lchip == drv_vchip_get_pp_base(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_opf_init(lchip, &p_usw_acl_master[lchip]->opf_type_aset, 1 , "opf-acl-aset"));
        opf.pool_index = 0;
        opf.pool_type  = p_usw_acl_master[lchip]->opf_type_aset;
        CTC_ERROR_RETURN(sys_usw_opf_init_offset(lchip, &opf, 1, SYS_ACL_ASET_MAX));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_acl_spool_init(uint8 lchip)
{
    uint32 ad_entry_size = 0;
    uint32 vedit_entry_size = 0;
    uint32 cid_ad_num = 0;
    ctc_spool_t spool;

    sal_memset(&spool, 0, sizeof(spool));

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsFlow_t, &ad_entry_size));
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsAclVlanActionProfile_t, &vedit_entry_size));
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsCategoryIdPairHashLeftAd_t, &cid_ad_num));

    ad_entry_size *= 2;
    /*spool for flow hash action*/
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = (ad_entry_size/SYS_ACL_USW_HASH_ACTION_BLOCK_SIZE)?(ad_entry_size/SYS_ACL_USW_HASH_ACTION_BLOCK_SIZE):1;
    spool.block_size = SYS_ACL_USW_HASH_ACTION_BLOCK_SIZE;
    spool.max_count = ad_entry_size*MCHIP_CAP(SYS_CAP_LOCAL_SLICE_NUM) ;
    spool.user_data_size = sizeof(sys_acl_hash_action_t);
    spool.spool_key = (hash_key_fn) _sys_usw_acl_hash_make_action;
    spool.spool_cmp = (hash_cmp_fn) _sys_usw_acl_hash_compare_action;
    spool.spool_alloc = (spool_alloc_fn) _sys_usw_acl_build_hash_ad_index;
    spool.spool_free = (spool_free_fn) _sys_usw_acl_free_hash_ad_index;
    p_usw_acl_master[lchip]->ad_spool = ctc_spool_create(&spool);

    /*spool for vlan edit profile*/
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = vedit_entry_size / MCHIP_CAP(SYS_CAP_ACL_VLAN_ACTION_SIZE_PER_BUCKET);
    spool.max_count = vedit_entry_size*MCHIP_CAP(SYS_CAP_LOCAL_SLICE_NUM) ;
    spool.user_data_size = sizeof(sys_acl_vlan_edit_t);
    spool.spool_key = (hash_key_fn) _sys_usw_acl_hash_make_vlan_edit;
    spool.spool_cmp = (hash_cmp_fn) _sys_usw_acl_hash_compare_vlan_edit;
    spool.spool_alloc = (spool_alloc_fn)_sys_usw_acl_build_vlan_edit_index;
    spool.spool_free = (spool_free_fn)_sys_usw_acl_free_vlan_edit_index;
    p_usw_acl_master[lchip]->vlan_edit_spool = ctc_spool_create(&spool);

    /*spool for cid hash action*/
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = cid_ad_num;
    spool.max_count = cid_ad_num * 2;
    spool.user_data_size = sizeof(sys_acl_cid_action_t);
    spool.spool_key = (hash_key_fn) _sys_usw_acl_hash_make_cid_ad;
    spool.spool_cmp = (hash_cmp_fn) _sys_usw_acl_hash_compare_cid_ad;
    spool.spool_alloc = (spool_alloc_fn)_sys_usw_acl_build_cid_ad_index;
    spool.spool_free = (spool_free_fn)_sys_usw_acl_free_cid_ad_index;
    p_usw_acl_master[lchip]->cid_spool = ctc_spool_create(&spool);

    return CTC_E_NONE;
}

int32
_sys_usw_acl_aset_init(uint8 lchip)
{
    sys_acl_aset_t* p_sys_aset = NULL;
    ctc_acl_aset_t support_aset[SYS_ACL_ACTION_NUM+1];
    ctc_acl_aset_t* p_aset = NULL;
    uint8 i = 0;
    uint8 pp_base = 0;
    uint16 aset_word = CTC_B2W_SIZE(CTC_ACL_FIELD_ACTION_NUM);
    uint32 basic_action[] = {
            CTC_ACL_FIELD_ACTION_CP_TO_CPU,
            CTC_ACL_FIELD_ACTION_COLOR,
            CTC_ACL_FIELD_ACTION_DSCP,
            CTC_ACL_FIELD_ACTION_REDIRECT_CANCEL_PKT_EDIT,
            CTC_ACL_FIELD_ACTION_REDIRECT_FILTER_ROUTED_PKT,
            CTC_ACL_FIELD_ACTION_CANCEL_DOT1AE,
            CTC_ACL_FIELD_ACTION_ECN,
            CTC_ACL_FIELD_ACTION_PRIORITY,
            CTC_ACL_FIELD_ACTION_DISABLE_ELEPHANT_LOG,
            CTC_ACL_FIELD_ACTION_TERMINATE_CID_HDR,
            CTC_ACL_FIELD_ACTION_CANCEL_NAT,
            CTC_ACL_FIELD_ACTION_TIMESTAMP,
            CTC_ACL_FIELD_ACTION_REFLECTIVE_BRIDGE_EN,
            CTC_ACL_FIELD_ACTION_PORT_ISOLATION_DIS,
            CTC_ACL_FIELD_ACTION_EXT_TIMESTAMP,
            CTC_ACL_FIELD_ACTION_DOT1AE_PERMIT_PLAIN_PKT,
            CTC_ACL_FIELD_ACTION_CRITICAL_PKT,
            CTC_ACL_FIELD_ACTION_QOS_TABLE_MAP,
            CTC_ACL_FIELD_ACTION_DENY_LEARNING,
            CTC_ACL_FIELD_ACTION_DISCARD,
            CTC_ACL_FIELD_ACTION_CANCEL_DISCARD,
            CTC_ACL_FIELD_ACTION_MICRO_FLOW_POLICER,
            CTC_ACL_FIELD_ACTION_MACRO_FLOW_POLICER,
            CTC_ACL_FIELD_ACTION_COS_HBWP_POLICER,
            CTC_ACL_FIELD_ACTION_COPP,
            CTC_ACL_FIELD_ACTION_CANCEL_IPFIX,
            CTC_ACL_FIELD_ACTION_CANCEL_IPFIX_LEARNING,
            CTC_ACL_FIELD_ACTION_INT,
            CTC_ACL_FIELD_ACTION_IFA,
            CTC_ACL_FIELD_ACTION_CANCEL_ALL
        };
   ctc_acl_aset_t basic_aset = {0};
   uint8 baisc_cnt = sizeof(basic_action)/sizeof(uint32);

    sal_memset(support_aset, 0, sizeof(support_aset));
   
    #define SYS_ACL_DEF_A(TYPE)      p_aset = &support_aset[TYPE];
    #define SYS_ACL_DEF_F(FIELD)    CTC_BMP_SET(p_aset->w, FIELD);
    #include "sys_usw_acl_aset.h"

    pp_base = drv_vchip_get_pp_base(lchip);
    if (DRV_FROM_AT(lchip) && lchip != pp_base)
    {
        p_usw_acl_master[lchip]->aset_vec = p_usw_acl_master[pp_base]->aset_vec;
        p_usw_acl_master[lchip]->support_aset = p_usw_acl_master[pp_base]->support_aset;
        return CTC_E_NONE;
    }
    p_usw_acl_master[lchip]->aset_vec = ctc_vector_init(8, (0xff + 1)/8);
    if(p_usw_acl_master[lchip]->aset_vec == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
    
    p_aset = mem_malloc(MEM_ACL_MODULE, SYS_ACL_ACTION_NUM*sizeof(ctc_acl_aset_t));
    if (p_aset == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
   
    sal_memset(p_aset, 0, SYS_ACL_ACTION_NUM*sizeof(ctc_acl_aset_t));
    
    if(DRV_FROM_AT(lchip))
    {
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_NUM].w, CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_NUM].w, CTC_ACL_FIELD_ACTION_XDATA);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_HASH_INGRESS].w, CTC_ACL_FIELD_ACTION_XDATA);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_EGRESS].w, CTC_ACL_FIELD_ACTION_CANCEL_IPFIX_LEARNING);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_EGRESS].w, CTC_ACL_FIELD_ACTION_IPFIX);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w, CTC_ACL_FIELD_ACTION_FPID);
    }
    if(DRV_FROM_TMM(lchip))
    {
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_HASH_INGRESS].w, CTC_ACL_FIELD_ACTION_SERVICE_ID);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w, CTC_ACL_FIELD_ACTION_SERVICE_ID);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w, CTC_ACL_FIELD_ACTION_INT);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w, CTC_ACL_FIELD_ACTION_IFA);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w, CTC_ACL_FIELD_ACTION_DISABLE_ECMP_DLB);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_NUM].w, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID);
    }
    if(DRV_IS_TSINGMA(lchip))
    {
        CTC_BMP_UNSET(support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w, CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w, CTC_ACL_FIELD_ACTION_EXT_TIMESTAMP);
        CTC_BMP_SET(support_aset[SYS_ACL_ACTION_TCAM_EGRESS].w, CTC_ACL_FIELD_ACTION_VXLAN_RSV_EDIT);
    }
    else if(DRV_IS_DUET2(lchip))
    {
         CTC_BMP_SET(support_aset[SYS_ACL_ACTION_HASH_INGRESS].w, CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH);
    }
    
    for(i = 0; i < aset_word; i++)
    {
        p_aset[SYS_ACL_ACTION_TCAM_INGRESS].w[i] = support_aset[SYS_ACL_ACTION_NUM].w[i] | support_aset[SYS_ACL_ACTION_TCAM_INGRESS].w[i];
        p_aset[SYS_ACL_ACTION_TCAM_EGRESS ].w[i] = support_aset[SYS_ACL_ACTION_NUM].w[i] | support_aset[SYS_ACL_ACTION_TCAM_EGRESS ].w[i];
        p_aset[SYS_ACL_ACTION_HASH_INGRESS].w[i] = support_aset[SYS_ACL_ACTION_HASH_INGRESS].w[i];
    }
    p_usw_acl_master[lchip]->support_aset = p_aset;

    /* tcam igs and tsingma egs */
    for(i= 0; i < baisc_cnt; i++)
    {
        CTC_BMP_SET(basic_aset.w, basic_action[i]);
    }
    /* def profile 0 */
    MALLOC_ZERO(MEM_ACL_MODULE, p_sys_aset, sizeof(sys_acl_aset_t));
    if(p_sys_aset == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
    if(p_usw_acl_master[pp_base]->no_aset)
    {
        sal_memset(p_sys_aset->w, 0xFF, sizeof(p_sys_aset->w));
    }
    else
    {
        sal_memcpy(p_sys_aset->w, basic_aset.w, sizeof(basic_aset.w));
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT_PORT);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_STATS);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DISABLE_ECMP_RR);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_LB_HASH_PROFILE);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_LB_HASH_ECMP_PROFILE);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DISABLE_LINKAGG_RR);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_LB_HASH_LAG_PROFILE);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REPLACE_LB_HASH);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_RANDOM_LOG);
        /* for user compatibility */
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_INTER_CN);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_SRC_CID);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_OAM);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_VLAN_EDIT);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_METADATA);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_STRIP_PACKET);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_IPFIX);
        CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID);
    }

    p_sys_aset->aset_id = 0;
    ctc_vector_add(p_usw_acl_master[lchip]->aset_vec, p_sys_aset->aset_id, p_sys_aset);

#if 0
    /* def profile 1 */
    MALLOC_ZERO(MEM_ACL_MODULE, p_sys_aset, sizeof(sys_acl_aset_t));
    if(p_sys_aset == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memcpy(p_sys_aset->w, basic_aset.w, sizeof(basic_aset.w));
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT_PORT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_VLAN_EDIT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_TRUNCATED_LEN);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_VLAN_EDIT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_STRIP_PACKET);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_IPFIX);
    p_sys_aset->aset_id = SYS_ACL_DEF_ASET_EDIT;
    p_sys_aset->u2_type = SYS_AD_UNION_G_4;
    ctc_vector_add(p_usw_acl_master[lchip]->aset_vec, p_sys_aset->aset_id, p_sys_aset);

    /* def profile 2 */
    MALLOC_ZERO(MEM_ACL_MODULE, p_sys_aset, sizeof(sys_acl_aset_t));
    if(p_sys_aset == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memcpy(p_sys_aset->w, basic_aset.w, sizeof(basic_aset.w));
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT_PORT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_NPM_IM_FLOW_ID);
    p_sys_aset->aset_id = SYS_ACL_DEF_ASET_NPM;
    p_sys_aset->u2_type = SYS_AD_UNION_G_4;
    ctc_vector_add(p_usw_acl_master[lchip]->aset_vec, p_sys_aset->aset_id, p_sys_aset);
#endif
    /* egs from tmm */
    if(DRV_FROM_TMM(lchip))
    {
        MALLOC_ZERO(MEM_ACL_MODULE, p_sys_aset, sizeof(sys_acl_aset_t));
        if(p_sys_aset == NULL)
        {
            return CTC_E_NO_MEMORY;
        }
        if(DRV_FROM_AT(lchip))
        {
            CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_IPFIX);        //u2_gIpfix     //at
            //CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_IPFIX_HASH_SALT);    //u1_gOam   /at
            CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_CANCEL_IPFIX_LEARNING);  //ipfixOpCode	//at
            //CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_DOT1AE_SPI);     //at
        }
        else //DRV_IS_TMM(lchip)
        {
            CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_DOT1AE_CHAN_ID); //tmm
            /* u2 */
            CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_OAM);    //u2_gOam
        }

        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_TIMESTAMP);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_CANCEL_ALL);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_CANCEL_DISCARD);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_DISCARD);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_CP_TO_CPU);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_CANCEL_IPFIX);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_MICRO_FLOW_POLICER);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_MACRO_FLOW_POLICER);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_COS_HBWP_POLICER);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_COPP);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_TRUNCATED_LEN);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_STATS);
        //CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_VLAN_EDIT);    //u2_gCvlanAction + u1_gSvlanAction
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_RANDOM_LOG);
        CTC_BMP_SET(p_sys_aset->w,CTC_ACL_FIELD_ACTION_CANCEL_DOT1AE);
        p_sys_aset->aset_id = SYS_ACL_DEF_ASET_EGS_TCAM;
        p_sys_aset->type = SYS_ACL_ACTION_TCAM_EGRESS;
        /*CTC_ERROR_RETURN(_sys_usw_acl_check_aset(lchip, SYS_ACL_ACTION_TCAM_EGRESS, p_sys_aset));*/
        ctc_vector_add(p_usw_acl_master[lchip]->aset_vec, p_sys_aset->aset_id, p_sys_aset);
    }

    /* hash def aset */
    MALLOC_ZERO(MEM_ACL_MODULE, p_sys_aset, sizeof(sys_acl_aset_t));
    if(p_sys_aset == NULL)
    {
        return CTC_E_NO_MEMORY;
    }
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_CANCEL_ALL);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DENY_BRIDGE);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DENY_LEARNING);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DENY_ROUTE);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DISABLE_ELEPHANT_LOG);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DISCARD);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DSCP);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_CP_TO_CPU);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_METADATA);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT_PORT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_MICRO_FLOW_POLICER);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_MACRO_FLOW_POLICER);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_COS_HBWP_POLICER);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_STATS);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_TRUNCATED_LEN);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_CRITICAL_PKT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_LOGIC_PORT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_CANCEL_ACL_TCAM_EN);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DEST_CID);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_SRC_CID);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DISABLE_ECMP_RR);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_DISABLE_LINKAGG_RR);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_LB_HASH_ECMP_PROFILE);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_LB_HASH_LAG_PROFILE);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_REDIRECT_CANCEL_PKT_EDIT);
    CTC_BMP_SET(p_sys_aset->w, CTC_ACL_FIELD_ACTION_SERVICE_ID);
    p_sys_aset->aset_id = SYS_ACL_DEF_ASET_HASH;
    p_sys_aset->type = SYS_ACL_ACTION_HASH_INGRESS;

    /*CTC_ERROR_RETURN(_sys_usw_acl_check_aset(lchip, SYS_ACL_ACTION_HASH_INGRESS, p_sys_aset));*/
    ctc_vector_add(p_usw_acl_master[lchip]->aset_vec, p_sys_aset->aset_id, p_sys_aset);
        
    return CTC_E_NONE;
}



int32
_sys_usw_acl_init_league_bitmap(uint8 lchip)
{
    uint8 block1 = 0;
    uint8 block2 = 0;
    uint8 prio = 0;
    uint32 old_size = 0;
    uint32 new_size = 0;
    uint32               cmd = 0;
    uint32               bmp[ACL_IGS_BLK_MAX_NUM + ACL_EGS_BLK_MAX_NUM] = {0};
    ds_t  ds;
    sys_acl_league_t*    p_sys_league = NULL;
    sys_acl_league_t*    p_tmp_league = NULL;
    ctc_fpa_entry_t**    p_tmp_entries = NULL;

    p_sys_league = &(p_usw_acl_master[lchip]->league[0]);
    cmd = DRV_IOR(IpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), ds));
    bmp[0] = GetIpeAclQosCtl(V, acl0AdMergeBitMap_f, ds)<<1;
    p_sys_league->lkup_level_bitmap |= bmp[0];

    p_sys_league = &(p_usw_acl_master[lchip]->league[1]);
    bmp[1] = GetIpeAclQosCtl(V, acl1AdMergeBitMap_f, ds)<<2;
    p_sys_league->lkup_level_bitmap |= bmp[1];
    p_sys_league->lkup_level_bitmap &= ~(bmp[0]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[2]);
    bmp[2] = GetIpeAclQosCtl(V, acl2AdMergeBitMap_f, ds)<<3;
    p_sys_league->lkup_level_bitmap |= bmp[2];
    p_sys_league->lkup_level_bitmap &= ~(bmp[0]|bmp[1]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[3]);
    bmp[3] = GetIpeAclQosCtl(V, acl3AdMergeBitMap_f, ds)<<4;
    p_sys_league->lkup_level_bitmap |= bmp[3];
    p_sys_league->lkup_level_bitmap &= ~(bmp[0]|bmp[1]|bmp[2]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[4]);
    bmp[4] = GetIpeAclQosCtl(V, acl4AdMergeBitMap_f, ds)<<5;
    p_sys_league->lkup_level_bitmap |= bmp[4];
    p_sys_league->lkup_level_bitmap &= ~(bmp[0]|bmp[1]|bmp[2]|bmp[3]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[5]);
    bmp[5] = GetIpeAclQosCtl(V, acl5AdMergeBitMap_f, ds)<<6;
    p_sys_league->lkup_level_bitmap |= bmp[5];
    p_sys_league->lkup_level_bitmap &= ~(bmp[0]|bmp[1]|bmp[2]|bmp[3]|bmp[4]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[6]);
    bmp[6] = GetIpeAclQosCtl(V, acl6AdMergeBitMap_f, ds)<<7;
    p_sys_league->lkup_level_bitmap |= bmp[6];
    p_sys_league->lkup_level_bitmap &= ~(bmp[0]|bmp[1]|bmp[2]|bmp[3]|bmp[4]|bmp[5]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[7]);
    p_sys_league->lkup_level_bitmap &= ~(bmp[0]|bmp[1]|bmp[2]|bmp[3]|bmp[4]|bmp[5]|bmp[6]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[8]);
    cmd = DRV_IOR(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), ds));
    bmp[8] = GetEpeAclQosCtl(V, acl0AdMergeBitMap_f, ds)<<1;
    p_sys_league->lkup_level_bitmap |= bmp[8];

    p_sys_league = &(p_usw_acl_master[lchip]->league[9]);
    bmp[9] = GetEpeAclQosCtl(V, acl1AdMergeBitMap_f, ds)<<2;
    p_sys_league->lkup_level_bitmap |= bmp[9];
    p_sys_league->lkup_level_bitmap &= ~(bmp[8]);

    p_sys_league = &(p_usw_acl_master[lchip]->league[10]);
    p_sys_league->lkup_level_bitmap &= ~(bmp[8]|bmp[9]);

    for (block1=0; block1<ACL_IGS_BLOCK_MAX_NUM+ACL_EGS_BLOCK_MAX_NUM; block1++)
    {
        p_sys_league = &(p_usw_acl_master[lchip]->league[block1]);

        for (prio=0; prio<ACL_IGS_BLOCK_MAX_NUM; prio++)
        {
            block2 = ((block1 < ACL_IGS_BLOCK_MAX_NUM) ? prio: prio + ACL_IGS_BLOCK_MAX_NUM);
            if (block2 == block1)
            {
                continue;
            }

            if (!CTC_IS_BIT_SET(p_sys_league->lkup_level_bitmap, prio))
            {
                continue;
            }

            p_tmp_league = &(p_usw_acl_master[lchip]->league[block2]);
            p_tmp_league->merged_to = block1;

            p_sys_league->lkup_level_start[prio] = SYS_ACL_BLOCK(lchip, block1).fpab.entry_count;
            p_sys_league->lkup_level_count[prio] = SYS_ACL_BLOCK(lchip, block2).fpab.entry_count;

            old_size = sizeof(sys_acl_entry_t*) * SYS_ACL_BLOCK(lchip, block1).fpab.entry_count;
            SYS_ACL_BLOCK(lchip, block1).fpab.entry_count += SYS_ACL_BLOCK(lchip, block2).fpab.entry_count;
            SYS_ACL_BLOCK(lchip, block1).fpab.free_count  += SYS_ACL_BLOCK(lchip, block2).fpab.free_count;
            SYS_ACL_BLOCK(lchip, block1).fpab.sub_entry_count[CTC_FPA_KEY_SIZE_640] += SYS_ACL_BLOCK(lchip, block2).fpab.entry_count/8;
            SYS_ACL_BLOCK(lchip, block1).fpab.sub_free_count[CTC_FPA_KEY_SIZE_640]  += SYS_ACL_BLOCK(lchip, block2).fpab.entry_count/8;
            SYS_ACL_BLOCK(lchip, block1).fpab.sub_rsv_count[CTC_FPA_KEY_SIZE_640]  = 0;

            new_size = sizeof(sys_acl_entry_t*) * SYS_ACL_BLOCK(lchip, block1).fpab.entry_count;
            MALLOC_ZERO(MEM_ACL_MODULE, p_tmp_entries, new_size);
            if (NULL == p_tmp_entries)
            {
                return CTC_E_NO_MEMORY;
            }

            sal_memcpy(p_tmp_entries, SYS_ACL_BLOCK(lchip, block1).fpab.entries, old_size);
            mem_free(SYS_ACL_BLOCK(lchip, block1).fpab.entries);
            SYS_ACL_BLOCK(lchip, block1).fpab.entries = p_tmp_entries;

            sal_memset(&(SYS_ACL_BLOCK(lchip, block2).fpab),0, sizeof(ctc_fpa_block_t)-sizeof(sys_acl_entry_t*));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_acl_install_build_key_fn(uint8 lchip)
{
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_MAC] = _sys_usw_acl_add_mackey160_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_IPV4] =  _sys_usw_acl_add_l3key160_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_MPLS] =    NULL;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_IPV6] =    _sys_usw_acl_add_ipv6key320_field;

    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_HASH_MAC] =   (SYS_CB_ACL_BUILD_KEY_FUNC_T)_sys_usw_acl_add_hash_mac_key_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_HASH_IPV4] =  (SYS_CB_ACL_BUILD_KEY_FUNC_T)_sys_usw_acl_add_hash_ipv4_key_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_HASH_L2_L3] = (SYS_CB_ACL_BUILD_KEY_FUNC_T)_sys_usw_acl_add_hash_l2l3_key_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_HASH_MPLS] =  (SYS_CB_ACL_BUILD_KEY_FUNC_T)_sys_usw_acl_add_hash_mpls_key_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_HASH_IPV6] =  (SYS_CB_ACL_BUILD_KEY_FUNC_T)_sys_usw_acl_add_hash_ipv6_key_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_PBR_IPV4] =  NULL;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_PBR_IPV6] =  NULL;

    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_IPV4_EXT] = _sys_usw_acl_add_l3key320_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_MAC_IPV4] =   _sys_usw_acl_add_macl3key320_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_MAC_IPV4_EXT] =_sys_usw_acl_add_macl3key640_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_IPV6_EXT] =   _sys_usw_acl_add_ipv6key640_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_MAC_IPV6] =    _sys_usw_acl_add_macipv6key640_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_CID] =      _sys_usw_acl_add_cidkey160_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_INTERFACE] =    _sys_usw_acl_add_shortkey80_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_FWD] =      _sys_usw_acl_add_forwardkey320_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_FWD_EXT] =     _sys_usw_acl_add_forwardkey640_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_COPP] =      _sys_usw_acl_add_coppkey320_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_COPP_EXT] =   _sys_usw_acl_add_coppkey640_field;
    p_usw_acl_master[lchip]->build_key_func[CTC_ACL_KEY_UDF] =   _sys_usw_acl_add_udfkey320_field;
    return CTC_E_NONE;
}

int32
_sys_usw_acl_get_action_fn(uint8 lchip)
{
    p_usw_acl_master[lchip]->get_ad_func[SYS_ACL_ACTION_TCAM_INGRESS] = _sys_usw_acl_get_field_action_tcam_igs;
    if (NULL != MCHIP_ACL(lchip)->get_egs_action_field)
    {
        p_usw_acl_master[lchip]->get_ad_func[SYS_ACL_ACTION_TCAM_EGRESS] = (SYS_CB_ACL_GET_AD_FUNC_T)MCHIP_ACL(lchip)->get_egs_action_field;
    }
    else
    {
        p_usw_acl_master[lchip]->get_ad_func[SYS_ACL_ACTION_TCAM_EGRESS] = _sys_usw_acl_get_field_action_tcam_igs;
    }
    p_usw_acl_master[lchip]->get_ad_func[SYS_ACL_ACTION_HASH_INGRESS] = (SYS_CB_ACL_GET_AD_FUNC_T)_sys_usw_acl_get_field_action_hash_igs;

    return CTC_E_NONE;
}
int32 sys_usw_acl_set_upa_en(uint8 lchip)
{
    uint8 block_id = 0;
    sys_acl_block_t* p_acb = NULL;

    SYS_ACL_INIT_CHECK();
    if(p_usw_acl_master[lchip]->upa_en)
    {
        return CTC_E_NONE;
    }
    SYS_USW_ACL_LOCK(lchip);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_MASTER, 1);
    p_usw_acl_master[lchip]->upa_en = 1;
    for (block_id = 0; block_id < p_usw_acl_master[lchip]->igs_block_num+p_usw_acl_master[lchip]->egs_block_num; block_id++)
    {
        p_acb = &SYS_ACL_BLOCK(lchip, block_id);
        p_acb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_80] = (DRV_FROM_TMM(lchip) && block_id<p_usw_acl_master[lchip]->igs_block_num)?
                                                           0:
                                                           p_acb->fpab.entry_count;
        p_acb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_80] = (DRV_FROM_TMM(lchip) && block_id<p_usw_acl_master[lchip]->igs_block_num)?
                                                          0:
                                                          p_acb->fpab.entry_count;
        p_acb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_160] = (DRV_FROM_TMM(lchip) && block_id<p_usw_acl_master[lchip]->igs_block_num)?
                                                            p_acb->fpab.entry_count:
                                                            0;
        p_acb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_160] = (DRV_FROM_TMM(lchip) && block_id<p_usw_acl_master[lchip]->igs_block_num)?
                                                           p_acb->fpab.entry_count:
                                                           0;
        p_acb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
        p_acb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_320] = 0;
        p_acb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
        p_acb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
    }
     SYS_USW_ACL_UNLOCK(lchip);
    return CTC_E_NONE;
}

void
sys_usw_acl_split_fpa_block(uint8 lchip, uint16 entry_cnt, sys_acl_fpa_ecnt_t p_ecnt)
{
    p_ecnt[CTC_FPA_KEY_SIZE_640] = (entry_cnt/8)&0xFFF8;
    p_ecnt[CTC_FPA_KEY_SIZE_320] = (entry_cnt*3/8)&0xFFF4;
    p_ecnt[CTC_FPA_KEY_SIZE_160] = entry_cnt - p_ecnt[CTC_FPA_KEY_SIZE_320] - p_ecnt[CTC_FPA_KEY_SIZE_640];
    p_ecnt[CTC_FPA_KEY_SIZE_80]  = 0;
}

#define _ACL_DUMP_INFO_
int32
_sys_usw_acl_show_field_range(uint8 lchip, sys_acl_field_range_t* p_range)
{
    uint8 show_num = 1;
    uint8 index = 0;
    char* str_type[] = {"None",
                    "Pkt-len",
                    "L4-src-port",
                    "L4-dst-port",
                    "Svlan",
                    "Cvlan",
                    "Udf","Sudf"};

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Field-Range   Total: %-4u Used: %-4u\n", p_range->entry_num,
                                                        p_range->entry_num - p_range->free_num);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10s%-12s%-10s%-8s%-8s%s\n", "No.", "TYPE", "RANGE_ID", "MIN", "MAX", "REF_CNT");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-------------------------------------------------------\n");

    for (index = 0; index < p_range->entry_num; index++)
    {
        if (p_range->range[index].range_type != ACL_RANGE_TYPE_NONE)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10u%-12s%-10u%-8u%-8u%u\n",
                    show_num,
                    str_type[p_range->range[index].range_type],
                    index,
                    p_range->range[index].min, p_range->range[index].max, p_range->range[index].ref);
            show_num++;
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_acl_show_field_range(uint8 lchip)
{
    sys_acl_field_range_t* p_range = NULL;

    SYS_ACL_INIT_CHECK();
    SYS_USW_ACL_LOCK(lchip);

    p_range = p_usw_acl_master[lchip]->field_range[0];
    _sys_usw_acl_show_field_range(lchip, p_range);

    p_range = p_usw_acl_master[lchip]->field_range[1+CTC_INGRESS];
    if (p_range != NULL)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n\nProgram ACL field range:\n");
        _sys_usw_acl_show_field_range(lchip, p_range);
    }

    p_range = p_usw_acl_master[lchip]->field_range[1+CTC_EGRESS];
    if (p_range != NULL)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n\nEgress Program ACL field range:\n");
        _sys_usw_acl_show_field_range(lchip, p_range);
    }

    SYS_USW_ACL_UNLOCK(lchip);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_acl_hash_traverse_cb_get_entry_cnt(sys_acl_entry_t* pe, uint32* p_cb_para)
{
    uint32* pd = NULL;

    pd = (void*)p_cb_para + sizeof(uint32)*(CTC_ACL_KEY_NUM+CTC_ACL_KEY_NUM-CTC_ACL_KEY_FLEX_BASE);

    if(pe)
    {
        if(!SYS_ACL_KEY_IS_FLEX(pe->key_type) || ACL_ENTRY_IS_TCAM(pe))
        {
            p_cb_para[pe->key_type]++;
        }
        else /* hash flex */
        {
            p_cb_para[pe->key_type+(CTC_ACL_KEY_NUM-CTC_ACL_KEY_FLEX_BASE)]++;
        }

        if(ACL_ENTRY_IS_TCAM(pe))   /*cnt tcam entry by ad type*/
        {
            pd[pe->ad_type]++;
        }

    }
    return CTC_E_NONE;
}

int32
sys_usw_acl_show_status(uint8 lchip)
{
#define ACL_FMT_BLK_INFO    "%6d/%-6d"
    uint16         idx;
    uint8          block_id  = 0;
    uint8          key_used_bmp = 0;
    uint32         need_continue[2] = {0};
    uint8   i = 0;
    uint32*        per_type_cnt = NULL;
    uint32*        ad_type_cnt =NULL;
    char*  ing_acl_type[8] = {"80 bit(I)", "160bit(I)", "320bit(I)", "640bit(I)"};
    char*  egr_acl_type[8] = {"80 bit(E)", "160bit(E)", "320bit(E)", "640bit(E)"};
    _acl_cb_para_t para;
    sys_acl_block_t* pb = NULL;

    SYS_ACL_INIT_CHECK();

    SYS_USW_ACL_LOCK(lchip);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n================= ACL Overall Status ==================\n");

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#0 Group Status\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------\n");

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-----------------****Inner Acl Group****--------------- \n");
    sal_memset(&para, 0, sizeof(_acl_cb_para_t));
    para.count = 0;
    para.lchip = lchip;
    ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                              (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_inner_gid, &para);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Total group count :%u \n", 5);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-----------------****Outer Acl Group****--------------- \n");
    sal_memset(&para, 0, sizeof(_acl_cb_para_t));
    para.count = 0;
    para.lchip = lchip;
    ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                              (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_outer_gid, &para);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Total group count :%u \n", para.count);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#1 Block Status \n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"----------------------------------------------------------------------------------------------------------------------------------\n");

    for (i=0; i < (p_usw_acl_master[lchip]->igs_block_num >> 3); i++)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-14s    ", "Size\\Block");
        for (block_id = 0; block_id < 8; block_id++)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-13d", block_id+(i<<3));
        }

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");

        for (idx = 0; idx < CTC_FPA_KEY_SIZE_NUM; idx++)
        {
            if (DRV_FROM_TMM(lchip) && idx == 0)
            {
                continue;
            }

            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-11s ",
                ((DRV_FROM_TMM(lchip)&&idx==CTC_FPA_KEY_SIZE_640)?"480bit(I)":ing_acl_type[idx]));
            for (block_id = 0; block_id < 8; block_id++)
            {
                if (CTC_BMP_ISSET(need_continue, block_id+(i<<3)))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO, 0, 0);
                    continue;
                }
                pb = &SYS_ACL_BLOCK(lchip, block_id+(i<<3));
                _sys_usw_acl_get_key_size_bitmap(lchip, pb, &key_used_bmp, CTC_INGRESS);
                if (CTC_IS_BIT_SET(key_used_bmp, CTC_FPA_KEY_SIZE_80))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO,
                                 (pb->fpab.entry_count - pb->fpab.free_count),
                                 pb->fpab.entry_count);
                    CTC_BMP_SET(need_continue, block_id+(i<<3));
                }
                else if(SYS_USW_ACL_UPA_EN(lchip, CTC_INGRESS))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO,
                                 idx? (pb->fpab.entry_count - pb->fpab.free_count)>>(pb->fpab.same_size?0:1): 0,
                                 idx? pb->fpab.entry_count>>(pb->fpab.same_size?0:1): 0);
                    idx? CTC_BMP_SET(need_continue, block_id+(i<<3)): CTC_BMP_UNSET(need_continue, block_id+(i<<3));
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO,
                                 (pb->fpab.sub_entry_count[idx] - pb->fpab.sub_free_count[idx]),
                                 pb->fpab.sub_entry_count[idx]);

                }
            }
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        }

        if(i > (p_usw_acl_master[lchip]->egs_block_num >>3))
        {
            continue;
        }
        for (idx = 0; idx < CTC_FPA_KEY_SIZE_NUM; idx++)
        {
            if (DRV_FROM_AT(lchip) && idx == 0)
            {
                continue;
            }
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-11s ",
                ((DRV_FROM_AT(lchip)&&idx==CTC_FPA_KEY_SIZE_640)?"480bit(E)":egr_acl_type[idx]));
            for (block_id = p_usw_acl_master[lchip]->igs_block_num;
                block_id < p_usw_acl_master[lchip]->igs_block_num + 8;
            block_id++)
            {
                if (((block_id -p_usw_acl_master[lchip]->igs_block_num)+(i<<3)) >= p_usw_acl_master[lchip]->egs_block_num)
                {
                    break;
                }
                if (CTC_BMP_ISSET(need_continue, block_id+(i<<3)))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO, 0, 0);
                    continue;
                }
                pb = &SYS_ACL_BLOCK(lchip, block_id+(i<<3));
                _sys_usw_acl_get_key_size_bitmap(lchip, pb, &key_used_bmp, CTC_EGRESS);
                if (CTC_IS_BIT_SET(key_used_bmp, CTC_FPA_KEY_SIZE_80))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO,
                                 (pb->fpab.entry_count - pb->fpab.free_count),
                                 pb->fpab.entry_count);
                    CTC_BMP_SET(need_continue, block_id+(i<<3));
                }
                else if(SYS_USW_ACL_UPA_EN(lchip, CTC_EGRESS))
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO,
                                 idx? (pb->fpab.entry_count - pb->fpab.free_count)>>(pb->fpab.same_size?0:1): 0,
                                 idx? pb->fpab.entry_count>>(pb->fpab.same_size?0:1): 0);
                    idx? CTC_BMP_SET(need_continue, block_id+(i<<3)): CTC_BMP_UNSET(need_continue, block_id+(i<<3));
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, ACL_FMT_BLK_INFO,
                                 (SYS_ACL_BLOCK(lchip, block_id+(i<<3)).fpab.sub_entry_count[idx] - SYS_ACL_BLOCK(lchip, block_id+(i<<3)).fpab.sub_free_count[idx]),
                                 SYS_ACL_BLOCK(lchip, block_id+(i<<3)).fpab.sub_entry_count[idx]);
                }
            }
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
    }

    if(NULL == (per_type_cnt = mem_malloc(MEM_ACL_MODULE, sizeof(uint32)*(CTC_ACL_KEY_NUM+CTC_ACL_KEY_NUM-CTC_ACL_KEY_FLEX_BASE) +
    sizeof(uint32)*SYS_ACL_AD_TYPE_NUM)))
    {
        SYS_USW_ACL_UNLOCK(lchip);
        return CTC_E_NO_MEMORY;
    }
    /* (rsv key entry cnt + tcam flex entry cnt + hash flex entry cnt) + ad type cnt*/
    sal_memset(per_type_cnt, 0, sizeof(uint32)*(CTC_ACL_KEY_NUM+CTC_ACL_KEY_NUM-CTC_ACL_KEY_FLEX_BASE) +
    sizeof(uint32)*SYS_ACL_AD_TYPE_NUM);
    ctc_hash_traverse_through(p_usw_acl_master[lchip]->entry,
                                  (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_get_entry_cnt, per_type_cnt);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#2 Tcam Entry Status :\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Mac",  per_type_cnt[CTC_ACL_KEY_MAC]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Ipv4", per_type_cnt[CTC_ACL_KEY_IPV4]+per_type_cnt[CTC_ACL_KEY_IPV4_EXT]+per_type_cnt[CTC_ACL_KEY_MAC_IPV4]+per_type_cnt[CTC_ACL_KEY_MAC_IPV4_EXT]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Ipv6", per_type_cnt[CTC_ACL_KEY_IPV6]+per_type_cnt[CTC_ACL_KEY_IPV6_EXT]+per_type_cnt[CTC_ACL_KEY_MAC_IPV6]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Cid",  per_type_cnt[CTC_ACL_KEY_CID]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Intf", per_type_cnt[CTC_ACL_KEY_INTERFACE]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Fwd",  per_type_cnt[CTC_ACL_KEY_FWD]+per_type_cnt[CTC_ACL_KEY_FWD_EXT]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Copp", per_type_cnt[CTC_ACL_KEY_COPP]+per_type_cnt[CTC_ACL_KEY_COPP_EXT]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Udf", per_type_cnt[CTC_ACL_KEY_UDF]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Stk Hdr", per_type_cnt[CTC_ACL_KEY_STK_HDR]);
    for (idx=CTC_ACL_KEY_FLEX_BASE; idx<=CTC_ACL_KEY_FLEX_END; idx++)
    {
        if (!per_type_cnt[idx])
        {
            continue;
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Flex(%03d) entries: %u \n", idx, per_type_cnt[idx]);
    }
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#3 Hash Entry Status :\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Hash-Mac",  per_type_cnt[CTC_ACL_KEY_HASH_MAC]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Hash-Ipv4", per_type_cnt[CTC_ACL_KEY_HASH_IPV4]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Hash-Ipv6", per_type_cnt[CTC_ACL_KEY_HASH_IPV6]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Hash-MPLS", per_type_cnt[CTC_ACL_KEY_HASH_MPLS]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Hash-L2L3", per_type_cnt[CTC_ACL_KEY_HASH_L2_L3]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s entries: %u \n", "Hash-nsh", per_type_cnt[CTC_ACL_KEY_HASH_NSH]);
    if (DRV_FROM_AT(lchip))
    {
        for (idx=CTC_ACL_KEY_FLEX_BASE; idx<=CTC_ACL_KEY_FLEX_END; idx++)
        {
            if (!per_type_cnt[idx+(CTC_ACL_KEY_NUM-CTC_ACL_KEY_FLEX_BASE)])
            {
                continue;
            }
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Flex(%3d) entries: %u \n", idx, per_type_cnt[idx+(CTC_ACL_KEY_NUM-CTC_ACL_KEY_FLEX_BASE)]);
        }
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#4 Spool Status :\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------\n");
    SYS_USW_ACL_ERROR_RETURN_UNLOCK( _sys_usw_acl_show_spool_status(lchip));
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#5 Tcam Resource Status :\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-9s  %-10s  %-10s  %-12s\n","Tcam Block", "used_count", "free_count", "total_count");
    for (block_id = 0; block_id < p_usw_acl_master[lchip]->igs_block_num+p_usw_acl_master[lchip]->egs_block_num; block_id++)
    {
        char tcam_block[20] = {0};

        if (block_id < p_usw_acl_master[lchip]->igs_block_num)
        {
            sal_sprintf(tcam_block, "%s  %d", "IGS", block_id);
        }
        else
        {
            sal_sprintf(tcam_block, "%s  %d", "EGS", block_id - p_usw_acl_master[lchip]->igs_block_num);
        }

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10s  %-10u  %-10u  %-12u\n",tcam_block, \
                            SYS_ACL_BLOCK(lchip, block_id).fpab.entry_count - SYS_ACL_BLOCK(lchip, block_id).fpab.free_count,
                            SYS_ACL_BLOCK(lchip, block_id).fpab.free_count, SYS_ACL_BLOCK(lchip, block_id).fpab.entry_count);
    }
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");

    ad_type_cnt = (void*)per_type_cnt + sizeof(uint32)*(CTC_ACL_KEY_NUM+CTC_ACL_KEY_NUM-CTC_ACL_KEY_FLEX_BASE);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"#6 Tcam Ad Type Status :\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-15s %-15s\n","Ad Type", "entry_count");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-15s %u \n", "Redirect", ad_type_cnt[SYS_ACL_AD_TYPE_REDIRECT]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-15s %u \n", "Stats", ad_type_cnt[SYS_ACL_AD_TYPE_STATS]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-15s %u \n", "Exception",  ad_type_cnt[SYS_ACL_AD_TYPE_EXCEPTION]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-15s %u \n", "Normal", ad_type_cnt[SYS_ACL_AD_TYPE_DISABLE]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");

    mem_free(per_type_cnt);

    SYS_USW_ACL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_acl_show_tcam_alloc_status(uint8 lchip, uint8 dir, uint8 block_id, uint8 detail, uint8 is_virtual)
{
    char* dir_str[2] = {"Ingress", "Egress"};
    char* key_str[4] = {"80 bit", "160bit", "320bit", "640bit"};
    sys_acl_block_t *p_block = NULL;
    ctc_fpa_block_t* pb = NULL;
    ctc_fpa_block_t* pb_part = NULL;
    uint8 fpa_block_id = 0;
    uint8 idx = 0;
    uint8 step = 1;

    SYS_ACL_INIT_CHECK();
    CTC_MAX_VALUE_CHECK(block_id, p_usw_acl_master[lchip]->igs_block_num - 1);

    fpa_block_id = block_id;
    if(CTC_EGRESS == dir)
    {
        CTC_MAX_VALUE_CHECK(block_id, p_usw_acl_master[lchip]->egs_block_num - 1);
        fpa_block_id += p_usw_acl_master[lchip]->igs_block_num;
    }

    SYS_USW_ACL_LOCK(lchip);

    p_block = &(SYS_ACL_BLOCK(lchip, fpa_block_id));
    pb = &p_block->fpab;

    if (is_virtual )
    {
        if (pb->vblock == NULL)
        {
            SYS_USW_ACL_UNLOCK(lchip);
            return 0;
        }

        pb = pb->vblock;
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\nblock id: %d, dir: %s\n", block_id, dir_str[dir]);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n(unit %dbit)  entry count: %d, used count: %d", pb->same_size?160:80,pb->entry_count, pb->entry_count - pb->free_count);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n------------------------------------------------------------------\n");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s%-15s%-15s%-15s%-15s\n", "key size", "range", "entry count", "used count", "rsv count");

    if (pb->sub_entry_count[CTC_FPA_KEY_SIZE_80] != pb->sub_free_count[CTC_FPA_KEY_SIZE_80])
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s[%4d,%4d]    %-15u%-15u%-15u\n", "80 bit", 0,
                                        pb->entry_count - 1,
                                        pb->entry_count, pb->entry_count - pb->free_count,
                                        pb->free_count);
    }
    else if (SYS_USW_ACL_UPA_EN(lchip, dir))
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s[%4d,%4d]    %-15u%-15u%-15u\n", "160 bit", 0,
                                        pb->entry_count - 1,
                                        pb->entry_count>>(p_block->fpab.same_size?0:1), (pb->entry_count - pb->free_count)>>(p_block->fpab.same_size?0:1),
                                        pb->free_count>>(p_block->fpab.same_size?0:1));
    }
    else
    {
        for(idx = 0; idx < CTC_FPA_KEY_SIZE_NUM; idx++)
        {
            if(pb->sub_entry_count[idx] > 0)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s[%4d,%4d]    %-15u%-15u%-15u\n",
                                               ((pb->same_size&&idx==CTC_FPA_KEY_SIZE_640)?"480bit":key_str[idx]),
                                                pb->start_offset[idx],
                                                pb->start_offset[idx] + pb->sub_entry_count[idx] * step - 1,
                                                pb->sub_entry_count[idx], pb->sub_entry_count[idx] - pb->sub_free_count[idx],
                                                pb->sub_free_count[idx]);
            }

            if (!DRV_FROM_TMM(lchip))
            {
                step = step * 2;
            }
        }
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"------------------------------------------------------------------\n");

    if (detail)
    {
        uint32 i = 0;
        uint8 part = 0;
        ctc_fpa_entry_t*   pe = NULL;


        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-7s%s %12s\n", " ", "Index","Entry id");

        for (idx = 0; idx < CTC_FPA_KEY_SIZE_NUM; idx++)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s ------------------------------\n", (pb->same_size&&idx==CTC_FPA_KEY_SIZE_640)?"480bit":key_str[idx]);
            step = DRV_FROM_TMM(lchip) ? 0 : idx;
            for (i = pb->start_offset[idx]; i < pb->start_offset[idx] + (pb->sub_entry_count[idx] << step); i += (1 << step))
            {
                part = 0;
                pe = NULL;
                pb_part = pb;

                while (pb_part)
                {
                    pe = pb_part->entries[i];

                    if (pe != NULL)
                    {
                        break;
                    }

                    pb_part = pb_part->next;
                }

                if (pe == NULL)
                {
                    continue;
                }

                pb_part = pb;

                while (pb_part)
                {
                    pe = pb_part->entries[i];

                    if (part == 0)
                    {
                        part = 1;
                        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%14d", i);
                    }

                    if (pe == NULL || idx != pe->key_size)
                    {
                        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%12s", "-");
                    }
                    else
                    {
                        char    str[35]     = {0};
                        char    format[10]  = {0};
                        if(SYS_ACL_SHOW_IN_HEX <= pe->entry_id)
                        {
                            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," %12s", CTC_DEBUG_HEX_FORMAT(str, format, pe->entry_id, 8, U));
                        }
                        else
                        {
                            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," %12u", pe->entry_id);
                        }
                    }

                    pb_part = pb_part->next;
                }

                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
            }
        }
    }

    SYS_USW_ACL_UNLOCK(lchip);

    return CTC_E_NONE;
}

/** show acl entry **
 * type = 0 :by all
 * type = 1 :by entry
 * type = 2 :by group
 * type = 3 :by priority
 */
int32
sys_usw_acl_show_entry( uint8 lchip,
                        uint8 type,
                        uint32 param,
                        uint16 key_type,
                        uint8 detail,
                        ctc_field_key_t* p_grep,
                        uint8 grep_cnt,
                        uint8 show_inner)
{
    uint8 grep_i = 0;
    SYS_ACL_INIT_CHECK();
    /* CTC_ACL_KEY_NUM represents all type*/
    //CTC_MAX_VALUE_CHECK(type, CTC_ACL_KEY_NUM); need check when type > 255
    CTC_PTR_VALID_CHECK(p_grep);
    CTC_MAX_VALUE_CHECK(grep_cnt, 8);

    for (grep_i = 0; grep_i < grep_cnt; grep_i++)
    {
        if (CTC_FIELD_KEY_PORT == p_grep[grep_i].type || CTC_FIELD_KEY_AWARE_TUNNEL_INFO == p_grep[grep_i].type
            || CTC_FIELD_KEY_SVLAN_RANGE == p_grep[grep_i].type || CTC_FIELD_KEY_CVLAN_RANGE == p_grep[grep_i].type
            || CTC_FIELD_KEY_IP_PKT_LEN_RANGE == p_grep[grep_i].type || CTC_FIELD_KEY_L4_SRC_PORT_RANGE == p_grep[grep_i].type || CTC_FIELD_KEY_L4_DST_PORT_RANGE == p_grep[grep_i].type)
        {
            return CTC_E_NOT_SUPPORT;    /* not support grep CTC_FIELD_KEY_PORT or CTC_FIELD_KEY_AWARE_TUNNEL_INFO */
        }
    }

    SYS_USW_ACL_LOCK(lchip);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-8s%-12s%-12s%-4s%-12s%-8s%-18s%-8s%-10s%s\n", "No.", "ENTRY_ID", "GROUP_ID", "HW", "E_PRI", "G_PRI", "TYPE", "INDEX","ACTION", "SIZE");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-------------------------------------------------------------------------------------------------\n");

    switch (type)
    {
    case 0:
        SYS_USW_ACL_ERROR_RETURN_UNLOCK(_sys_usw_acl_show_entry_all(lchip, param, key_type, detail,type, p_grep, grep_cnt, show_inner));
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        break;

    case 1:
        SYS_USW_ACL_ERROR_RETURN_UNLOCK(_sys_usw_acl_show_entry_by_entry_id(lchip, param, key_type, detail,type, p_grep, grep_cnt, show_inner));
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        break;

    case 2:
        SYS_USW_ACL_ERROR_RETURN_UNLOCK(_sys_usw_acl_show_entry_by_group_id(lchip, param, key_type, detail,type, p_grep, grep_cnt, show_inner));
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        break;

    case 3:
        SYS_USW_ACL_ERROR_RETURN_UNLOCK(_sys_usw_acl_show_entry_by_priority(lchip, param, key_type, detail,type, p_grep, grep_cnt, show_inner));
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        break;

    case 4:
        SYS_USW_ACL_ERROR_RETURN_UNLOCK(_sys_usw_acl_show_entry_by_lkup_level(lchip, param, key_type, detail,type, p_grep, grep_cnt, show_inner));
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        break;

    default:
        SYS_USW_ACL_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;
    }

    SYS_USW_ACL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_acl_show_entry_distribution(uint8 lchip, uint8 dir, uint8 priority)
{
    uint8 block_id = 0;
    uint8 step = 0;
    uint32 idx = 0;
    uint8 idx2 = 0;
    uint8 idx3 = 0;
    uint8 cur_key = 0;
    uint8 next_key = 0;
    uint8 cur_level = priority;
    uint8 next_level = priority;
    uint8 count = 0;
    uint8 print_head = FALSE;
    uint8 is_program = (((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && dir == CTC_INGRESS) || DRV_FROM_AT(lchip)) ? TRUE : FALSE;
    sys_acl_block_t* pb = NULL;
    sys_acl_league_t* p_sys_league = NULL;
    char* key_desc[CTC_FPA_KEY_SIZE_NUM] = {"K80 ","K160","K320","K640"};
    uint8 key_step[CTC_FPA_KEY_SIZE_NUM] = {1,2,4,8};
    char buf[3][64];

#define KEYD(idx) ((is_program && idx==CTC_FPA_KEY_SIZE_640)?"K480":key_desc[idx])


    SYS_ACL_INIT_CHECK();
    CTC_MAX_VALUE_CHECK(priority, (CTC_INGRESS == dir ? ACL_IGS_BLOCK_MAX_NUM-1: ACL_EGS_BLOCK_MAX_NUM-1));

    SYS_USW_ACL_LOCK(lchip);

    sal_memset(buf, 0, sizeof(buf));
    block_id = ((dir == CTC_INGRESS) ? priority: priority + ACL_IGS_BLOCK_MAX_NUM);
    pb = &SYS_ACL_BLOCK(lchip, block_id);
    p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," %-14s%14s%14s%14s%14s%14s\n", "Key", "Total(I/C)", "Used(I/C)", "Free(I/C)", "StartIdx", "Step");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------------\n");
    if (pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_80] != pb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_80])
    {
        idx = CTC_FPA_KEY_SIZE_80;
        sal_sprintf(buf[0], "%u/%u", pb->fpab.entry_count, pb->fpab.entry_count);
        sal_sprintf(buf[1], "%u/%u", (pb->fpab.entry_count - pb->fpab.free_count), (pb->fpab.entry_count - pb->fpab.free_count));
        sal_sprintf(buf[2], "%u/%u", pb->fpab.free_count, pb->fpab.free_count);

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," %-14s%14s%14s%14s%14u%14u\n",
            KEYD(idx), buf[0], buf[1], buf[2], 0, 1);
    }
    else if (p_usw_acl_master[lchip]->upa_en)
    {
        idx = CTC_FPA_KEY_SIZE_160;
        sal_sprintf(buf[0], "%u/%u", pb->fpab.entry_count, pb->fpab.entry_count>>(pb->fpab.same_size?0:1));
        sal_sprintf(buf[1], "%u/%u", (pb->fpab.entry_count - pb->fpab.free_count), (pb->fpab.entry_count - pb->fpab.free_count)>>(pb->fpab.same_size?0:1));
        sal_sprintf(buf[2], "%u/%u", pb->fpab.free_count, pb->fpab.free_count>>(pb->fpab.same_size?0:1));

        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," %-14s%14s%14s%14s%14u%14u\n",
            KEYD(idx), buf[0], buf[1], buf[2], 0, 2);
    }
    else
    {
        for (idx=CTC_FPA_KEY_SIZE_160; idx<CTC_FPA_KEY_SIZE_NUM; idx++)
        {
            uint8 k_step = 0;

            k_step = is_program ? 1 : key_step[idx];
            sal_sprintf(buf[0], "%u/%u", pb->fpab.sub_entry_count[idx]*k_step, pb->fpab.sub_entry_count[idx]);
            sal_sprintf(buf[1], "%u/%u", (pb->fpab.sub_entry_count[idx] - pb->fpab.sub_free_count[idx])*k_step, pb->fpab.sub_entry_count[idx] - pb->fpab.sub_free_count[idx]);
            sal_sprintf(buf[2], "%u/%u", pb->fpab.sub_free_count[idx]*k_step, pb->fpab.sub_free_count[idx]);

            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," %-14s%14s%14s%14s%14u%14u\n",
                KEYD(idx), buf[0], buf[1], buf[2], pb->fpab.start_offset[idx], k_step);
        }
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"--------------------------------------------------------------------------------------\n");

    step = 1;
    for (idx = 0; idx < pb->fpab.entry_count; idx = idx + step)
    {
        print_head = FALSE;

        if (idx == 0)
        {
            print_head = TRUE;
        }

        if(idx >= pb->fpab.start_offset[CTC_FPA_KEY_SIZE_640] && (pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_640]))
        {
            next_key = CTC_FPA_KEY_SIZE_640;
        }
        else if(idx >= pb->fpab.start_offset[CTC_FPA_KEY_SIZE_320] && (pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_320]))
        {
            next_key = CTC_FPA_KEY_SIZE_320;
        }
        else if(idx >= pb->fpab.start_offset[CTC_FPA_KEY_SIZE_160] && (pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_160]))
        {
            next_key = CTC_FPA_KEY_SIZE_160;
        }
        else /*80 bit key*/
        {
            next_key = CTC_FPA_KEY_SIZE_80;
        }

        if ((pb->fpab.sub_entry_count[CTC_FPA_KEY_SIZE_80] != pb->fpab.sub_free_count[CTC_FPA_KEY_SIZE_80]))
        {
            next_key = CTC_FPA_KEY_SIZE_80;
        }
        else if (SYS_USW_ACL_UPA_EN(lchip, dir))
        {
            next_key = CTC_FPA_KEY_SIZE_160;
        }

        step = is_program ? 1 : key_step[next_key];

        if (idx > 0)
        {
            for (idx2 = ACL_IGS_BLOCK_MAX_NUM-1; idx2 > cur_level; idx2--)
            {
                if ((p_sys_league->lkup_level_start[idx2] > 0) && (idx >= p_sys_league->lkup_level_start[idx2]))
                {
                    next_level = idx2;
                    break;
                }
            }
        }

        if ((cur_key != next_key) || (cur_level != next_level))
        {
            if (idx != 0)
            {
                for (idx3=count; idx3 < 64; idx3++)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," ");
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," [%-2u]", count);
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
            }
            print_head = TRUE;
            count = 0;
            cur_key = next_key;
            cur_level = next_level;
        }
        else if (count >= 64)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," [%-2u]", count);
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
            print_head = TRUE;
            count = 0;
        }

        if (print_head)
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"[%-4s lv%u %5u] ", KEYD(next_key), next_level, idx);
        }

        if (idx == 0)
        {
            cur_key = next_key;
            cur_level = next_level;
        }

        if (pb->fpab.entries[idx])
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"1");
        }
        else
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"0");
        }

        count++;

        if (idx + step >= pb->fpab.entry_count)
        {
            for (idx3=count; idx3 < 64; idx3++)
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," ");
            }
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP," [%-2u]", count);
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\n");
        }
    }

    SYS_USW_ACL_UNLOCK(lchip);

    return CTC_E_NONE;
}

/** show acl entry **
 * type = 0 :by all
 */
int32
sys_usw_acl_show_group(uint8 lchip, uint8 type)
{
    _acl_cb_para_t para;
    SYS_ACL_INIT_CHECK();

    SYS_USW_ACL_LOCK(lchip);

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6s%-12s%-6s%-6s%-14s%-10s%s\n", "No.", "GROUP_ID", "DIR", "PRI", "TYPE", "ENTRY_NUM", "KEY");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-----------------------------------------------------------------------------------------\n");

    sal_memset(&para, 0, sizeof(_acl_cb_para_t));
    para.count = 0;
    para.lchip = 0;
    ctc_hash_traverse_through(p_usw_acl_master[lchip]->group,
                              (hash_traversal_fn) _sys_usw_acl_hash_traverse_cb_show_group, &para);
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"Total group count :%u \n", para.count);

    SYS_USW_ACL_UNLOCK(lchip);

    return CTC_E_NONE;
}

int32
sys_usw_acl_show_cid_pair(uint8 lchip, uint8 type)
{
    uint16  index = 0;
    uint16  num   = 0;
    uint32 cmd   = 0;
    uint32 ad_index = 0;
    uint16 dst_cid = 0;
    uint8  dst_cid_valid = 0;
    uint16 src_cid = 0;
    uint8  src_cid_valid = 0;
    ds_t  ds_key;
    ds_t  ds_mask;
    ds_t  ds_act;
    tbl_entry_t tcam_key;
    uint8 act_mode = 0;   /*0->over, 1->permit, 2->deny*/
    char* act_name[3] = {"Over Acl", "Permit", "Deny"};

    SYS_ACL_INIT_CHECK();

    SYS_USW_ACL_LOCK(lchip);

    sal_memset(&ds_key,   0, sizeof(ds_t));
    sal_memset(&ds_act,   0, sizeof(ds_t));
    tcam_key.data_entry = (uint32*)(&ds_key);
    tcam_key.mask_entry = (uint32*)(&ds_mask);

    if(0 == type || 2 == type)
    {
        num = 1;
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\nHash Key1: DsCategoryIdPairHashLeftKey, Ad1: DsCategoryIdPairHashLeftAd\n");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"No.   src-cid     dst-cid     action      key-index   offset    act-index\n");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-------------------------------------------------------------------------\n");

        for(index = 0; index < MCHIP_CAP(SYS_CAP_ACL_HASH_CID_KEY); index++)
        {
            /*get key*/
            cmd = DRV_IOR(DsCategoryIdPairHashLeftKey_t, DRV_ENTRY_FLAG);
            SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds_key));
            if(GetDsCategoryIdPairHashLeftKey(V, array_0_valid_f, &ds_key))
            {
                src_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_0_srcCategoryIdClassfied_f, &ds_key);
                dst_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_0_destCategoryIdClassfied_f, &ds_key);
                src_cid = GetDsCategoryIdPairHashLeftKey(V, array_0_srcCategoryId_f, &ds_key);
                dst_cid = GetDsCategoryIdPairHashLeftKey(V, array_0_destCategoryId_f, &ds_key);
                ad_index = GetDsCategoryIdPairHashLeftKey(V, array_0_adIndex_f, &ds_key);
                /*get ad*/
                cmd = DRV_IOR(DsCategoryIdPairHashLeftAd_t, DRV_ENTRY_FLAG);
                SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, ad_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds_act));
                act_mode = GetDsCategoryIdPairHashLeftAd(V, operationMode_f, &ds_act);
                if(act_mode)
                {
                    if(GetDsCategoryIdPairHashLeftAd(V, u1_g2_permit_f, &ds_act))
                    {
                        act_mode = 1;
                    }
                    else
                    {
                        act_mode = 2;
                    }
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6u", num);
                if(src_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", src_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                if(dst_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", dst_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s%-12u%-10u%-12u\n", act_name[act_mode], index, 0,ad_index);
                num++;
            }
            if(GetDsCategoryIdPairHashLeftKey(V, array_1_valid_f, &ds_key))
            {
                src_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_1_srcCategoryIdClassfied_f, &ds_key);
                dst_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_1_destCategoryIdClassfied_f, &ds_key);
                src_cid = GetDsCategoryIdPairHashLeftKey(V, array_1_srcCategoryId_f, &ds_key);
                dst_cid = GetDsCategoryIdPairHashLeftKey(V, array_1_destCategoryId_f, &ds_key);
                ad_index = GetDsCategoryIdPairHashLeftKey(V, array_1_adIndex_f, &ds_key);
                /*get ad*/
                cmd = DRV_IOR(DsCategoryIdPairHashLeftAd_t, DRV_ENTRY_FLAG);
                SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, ad_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds_act));
                act_mode = GetDsCategoryIdPairHashLeftAd(V, operationMode_f, &ds_act);
                if(act_mode)
                {
                    if(GetDsCategoryIdPairHashLeftAd(V, u1_g2_permit_f, &ds_act))
                    {
                        act_mode = 1;
                    }
                    else
                    {
                        act_mode = 2;
                    }
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6u", num);
                if(src_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", src_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                if(dst_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", dst_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s%-12u%-10u%-12u\n", act_name[act_mode], index, 1, ad_index);
                num++;
            }
        }

        num = 1;
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\nHash Key2: DsCategoryIdPairHashRightKey, Ad2: DsCategoryIdPairHashRightAd\n");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"No.   src-cid     dst-cid     action      key-index   offset    act-index\n");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-------------------------------------------------------------------------\n");
        for(index = 0; index < MCHIP_CAP(SYS_CAP_ACL_HASH_CID_KEY); index++)
        {
            /*get key*/
            cmd = DRV_IOR(DsCategoryIdPairHashRightKey_t, DRV_ENTRY_FLAG);
            SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds_key));
            if(GetDsCategoryIdPairHashRightKey(V, array_0_valid_f, &ds_key))
            {
                src_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_0_srcCategoryIdClassfied_f, &ds_key);
                dst_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_0_destCategoryIdClassfied_f, &ds_key);
                src_cid = GetDsCategoryIdPairHashRightKey(V, array_0_srcCategoryId_f, &ds_key);
                dst_cid = GetDsCategoryIdPairHashRightKey(V, array_0_destCategoryId_f, &ds_key);
                ad_index = GetDsCategoryIdPairHashRightKey(V, array_0_adIndex_f, &ds_key);
                /*get ad*/
                cmd = DRV_IOR(DsCategoryIdPairHashRightAd_t, DRV_ENTRY_FLAG);
                SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, ad_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds_act));
                act_mode = GetDsCategoryIdPairHashRightAd(V, operationMode_f, &ds_act);
                if(act_mode)
                {
                    if(GetDsCategoryIdPairHashRightAd(V, u1_g2_permit_f, &ds_act))
                    {
                        act_mode = 1;
                    }
                    else
                    {
                        act_mode = 2;
                    }
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6u", num);
                if(src_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", src_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                if(dst_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", dst_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s%-12u%-10u%-12u\n", act_name[act_mode], index, 0, ad_index);
                num++;
            }
            if(GetDsCategoryIdPairHashRightKey(V, array_1_valid_f, &ds_key))
            {
                src_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_1_srcCategoryIdClassfied_f, &ds_key);
                dst_cid_valid = GetDsCategoryIdPairHashLeftKey(V, array_1_destCategoryIdClassfied_f, &ds_key);
                src_cid = GetDsCategoryIdPairHashRightKey(V, array_1_srcCategoryId_f, &ds_key);
                dst_cid = GetDsCategoryIdPairHashRightKey(V, array_1_destCategoryId_f, &ds_key);
                ad_index = GetDsCategoryIdPairHashRightKey(V, array_1_adIndex_f, &ds_key);
                /*get ad*/
                cmd = DRV_IOR(DsCategoryIdPairHashRightAd_t, DRV_ENTRY_FLAG);
                SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, ad_index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds_act));
                act_mode = GetDsCategoryIdPairHashRightAd(V, operationMode_f, &ds_act);
                if(act_mode)
                {
                    if(GetDsCategoryIdPairHashRightAd(V, u1_g2_permit_f, &ds_act))
                    {
                        act_mode = 1;
                    }
                    else
                    {
                        act_mode = 2;
                    }
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6u", num);
                if(src_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", src_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                if(dst_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", dst_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s%-12u%-10u%-12u\n", act_name[act_mode], index, 1, ad_index);
                num++;
            }
        }

    }
    if(1 == type || 2 == type)
    {
        num = 1;
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"\nTcam Key: DsCategoryIdPairTcamKey, Ad: DsCategoryIdPairTcamAd\n");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"No.   src-cid     dst-cid     action      key-index   act-index\n");
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"---------------------------------------------------------------\n");
        sal_memset(&ds_key, 0, sizeof(ds_t));
        sal_memset(&ds_act, 0, sizeof(ds_t));
        for(index = 0; index < MCHIP_CAP(SYS_CAP_ACL_TCAM_CID_PAIR); index++)
        {
            /*get key*/
            cmd = DRV_IOR(DsCategoryIdPairTcamKey_t, DRV_ENTRY_FLAG);
            SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &tcam_key));
            src_cid_valid = GetDsCategoryIdPairTcamKey(V, srcCategoryIdClassfied_f, ds_key);
            dst_cid_valid = GetDsCategoryIdPairTcamKey(V, destCategoryIdClassfied_f, ds_key);
            src_cid = GetDsCategoryIdPairTcamKey(V, srcCategoryId_f, ds_key);
            dst_cid = GetDsCategoryIdPairTcamKey(V, destCategoryId_f, ds_key);
            if((src_cid_valid != 0) || (dst_cid_valid != 0))
            {
                /*get ad*/
                cmd = DRV_IOR(DsCategoryIdPairTcamAd_t, DRV_ENTRY_FLAG);
                SYS_USW_ACL_ERROR_RETURN_UNLOCK(DRV_IOCTL(lchip, index, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds_act));
                act_mode = GetDsCategoryIdPairTcamAd(V, operationMode_f, ds_act);
                if(act_mode)
                {
                    if(GetDsCategoryIdPairTcamAd(V, u1_g2_permit_f, &ds_act))
                    {
                        act_mode = 1;
                    }
                    else
                    {
                        act_mode = 2;
                    }
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-6u", num);
                if(src_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", src_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                if(dst_cid_valid)
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12u", dst_cid);
                }
                else
                {
                    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"*           ");
                }
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-12s%-12u%-12u\n", act_name[act_mode], index, index);
                num++;
            }
        }
    }
    SYS_USW_ACL_UNLOCK(lchip);
    return CTC_E_NONE;
}

int32
sys_usw_acl_show_flex_keygen(uint8 lchip, uint8 dir, uint8 key_type, uint32 eid, uint32* data)
{
    SYS_ACL_INIT_CHECK();
    SYS_USW_ACL_LOCK(lchip);
    if (MCHIP_ACL(lchip)->show_flex_keygen)
    {
        MCHIP_ACL(lchip)->show_flex_keygen(lchip, dir, key_type, eid, data);
    }
    SYS_USW_ACL_UNLOCK(lchip);
    return CTC_E_NONE;
}


#define _ACL_EXPAND_TCAM_

/*only used for ingress acl
level status is an array
0 : not use ext tcam
1 : use ext-tcam but there is no entry on ext-tcam
2 : use ext-tcam and there are entries on ext-tcam, but this entry can be move to other tcam
3 : can not move to other tcam

NOTE:
*/
int32 _sys_usw_acl_get_ext_tcam_status(uint8 lchip, uint8* level_status)
{
    uint8 idx = 0;
    int8 key_size = 0;
    uint8 can_be_compress = 0;
    uint8 exist_entry_in_ext_tcam = 0;
    uint8 step = 0;
    uint16 tmp_offset = 0;
    uint32 size = 0;
    ctc_fpa_block_t* pb = NULL;
    uint8 mem_id = 0;

    sal_memset(level_status, 0, sizeof(uint8)*p_usw_acl_master[lchip]->igs_block_num);
    for(idx=0; idx < p_usw_acl_master[lchip]->igs_block_num; idx++)
    {
        pb = &(p_usw_acl_master[lchip]->block[idx].fpab);
        if(idx==0 || idx==1 ||idx==4 || idx==5)
        {
            /*special process for scl and acl share one tcam*/
            CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, ((idx%2) ? DsScl3MacKey160_t: DsScl2MacKey160_t), &size));
            size *= 2;

            mem_id = SYS_USW_SCL_TCAM_BASE+(idx%2);
            if(size > SYS_USW_PRIVATE_TCAM_SIZE)
            {
                level_status[idx] = 3;
                continue;
            }
        }
        CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsAclQosKey80Ing0_t+idx, &size));
        mem_id = SYS_USW_ACL_TCAM_BASE+idx;
        if(size > SYS_USW_PRIVATE_TCAM_SIZE)
        {
            if(pb->entry_count == pb->free_count)
            {
                level_status[idx] = 1;
                continue;
            }

            can_be_compress = ((pb->entry_count-pb->free_count) <= SYS_USW_PRIVATE_TCAM_SIZE) ? 1:0;

            exist_entry_in_ext_tcam = 0;
            step = 8;
            for(key_size=CTC_FPA_KEY_SIZE_640; key_size >=0; key_size--)
            {
                tmp_offset = (pb->start_offset[key_size] > SYS_USW_PRIVATE_TCAM_SIZE) ? pb->start_offset[key_size] : SYS_USW_PRIVATE_TCAM_SIZE;

                for(;tmp_offset<(pb->sub_entry_count[key_size]*step+pb->start_offset[key_size]); tmp_offset+=step)
                {
                    if(pb->entries[tmp_offset])
                    {
                        exist_entry_in_ext_tcam = 1;
                        break;
                    }
                }
                if(exist_entry_in_ext_tcam || (pb->start_offset[key_size] <= SYS_USW_PRIVATE_TCAM_SIZE))
                {
                    break;
                }
                step = step/2;
            }
            level_status[idx] = (exist_entry_in_ext_tcam)?(can_be_compress?2:3):1;
        }
    }
    return CTC_E_NONE;
}

STATIC int32 _sys_usw_acl_do_adjust_ext_tcam(uint8 lchip, uint8 expand_blocks, uint8 compress_blocks, uint8* level_status)
{
    uint8 idx = 0;
    sys_acl_league_t* p_sys_league = NULL;
    ctc_fpa_block_t*  pb = NULL;
    uint16 tmp_count = 0;
    uint32 tmp_size = 0;
    ctc_fpa_entry_t** p_entries = NULL;
    uint8  mem_id;
    uint8  ext_mem_id;

    for(idx=0; idx < p_usw_acl_master[lchip]->igs_block_num; idx++)
    {
        pb = &(p_usw_acl_master[lchip]->block[idx].fpab);
        p_sys_league = &(p_usw_acl_master[lchip]->league[idx]);
        tmp_size = pb->entry_count*sizeof(ctc_fpa_entry_t*);
        ext_mem_id = SYS_USW_FLOW_EXT_TCAM_BASE + (idx & 0x3);
        if(CTC_IS_BIT_SET(compress_blocks, idx))
        {
            if(level_status[idx] == 2)
            {
                _sys_usw_acl_reorder_entry_up_to_down(lchip, p_sys_league);
            }
            p_usw_acl_master[lchip]->block[idx].entry_num -= SYS_USW_EXT_TCAM_SIZE;
            p_sys_league->lkup_level_count[idx] -= SYS_USW_EXT_TCAM_SIZE;
            pb->entry_count -= SYS_USW_EXT_TCAM_SIZE;
            pb->free_count -= SYS_USW_EXT_TCAM_SIZE;

            mem_id = SYS_USW_ACL_TCAM_BASE + idx;
            if (pb->sub_entry_count[CTC_FPA_KEY_SIZE_640] && pb->start_offset[CTC_FPA_KEY_SIZE_640] <= SYS_USW_PRIVATE_TCAM_SIZE)
            {
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_640] -= SYS_USW_EXT_TCAM_SIZE/8;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_640] -= SYS_USW_EXT_TCAM_SIZE/8;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;
            }
            else if (pb->sub_entry_count[CTC_FPA_KEY_SIZE_320] && pb->start_offset[CTC_FPA_KEY_SIZE_320] <= SYS_USW_PRIVATE_TCAM_SIZE)
            {
                pb->start_offset[CTC_FPA_KEY_SIZE_640] = SYS_USW_PRIVATE_TCAM_SIZE;
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;

                tmp_count = pb->sub_entry_count[CTC_FPA_KEY_SIZE_320]-pb->sub_free_count[CTC_FPA_KEY_SIZE_320];
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_320] = (SYS_USW_PRIVATE_TCAM_SIZE-pb->start_offset[CTC_FPA_KEY_SIZE_320])/4;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_320] = pb->sub_entry_count[CTC_FPA_KEY_SIZE_320]-tmp_count;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_320] = 0;
            }
            else if (pb->sub_entry_count[CTC_FPA_KEY_SIZE_160] && pb->start_offset[CTC_FPA_KEY_SIZE_160] <= SYS_USW_PRIVATE_TCAM_SIZE)
            {
                pb->start_offset[CTC_FPA_KEY_SIZE_640] = SYS_USW_PRIVATE_TCAM_SIZE;
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;

                pb->start_offset[CTC_FPA_KEY_SIZE_320] = SYS_USW_PRIVATE_TCAM_SIZE;
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_320] = 0;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_320] = 0;

                tmp_count = pb->sub_entry_count[CTC_FPA_KEY_SIZE_160]-pb->sub_free_count[CTC_FPA_KEY_SIZE_160];
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_160] = (SYS_USW_PRIVATE_TCAM_SIZE-pb->start_offset[CTC_FPA_KEY_SIZE_160])/2;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_160] = pb->sub_entry_count[CTC_FPA_KEY_SIZE_160]-tmp_count;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_160] = 0;
            }
            else if (pb->sub_entry_count[CTC_FPA_KEY_SIZE_80] && pb->start_offset[CTC_FPA_KEY_SIZE_80] <= SYS_USW_PRIVATE_TCAM_SIZE)
            {
                pb->start_offset[CTC_FPA_KEY_SIZE_640] = SYS_USW_PRIVATE_TCAM_SIZE;
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;

                pb->start_offset[CTC_FPA_KEY_SIZE_320] = SYS_USW_PRIVATE_TCAM_SIZE;
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_320] = 0;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_320] = 0;

                pb->start_offset[CTC_FPA_KEY_SIZE_160] = SYS_USW_PRIVATE_TCAM_SIZE;
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_160] = 0;
                pb->sub_free_count[CTC_FPA_KEY_SIZE_160] = 0;
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_160] = 0;

                tmp_count = pb->sub_entry_count[CTC_FPA_KEY_SIZE_80]-pb->sub_free_count[CTC_FPA_KEY_SIZE_80];
                pb->sub_entry_count[CTC_FPA_KEY_SIZE_80] = (SYS_USW_PRIVATE_TCAM_SIZE-pb->start_offset[CTC_FPA_KEY_SIZE_80]);
                pb->sub_free_count[CTC_FPA_KEY_SIZE_80] = (pb->sub_entry_count[CTC_FPA_KEY_SIZE_80]-tmp_count);
                pb->sub_rsv_count[CTC_FPA_KEY_SIZE_80] = 0;
            }
        }
        else if(CTC_IS_BIT_SET(expand_blocks, idx))
        {
            p_usw_acl_master[lchip]->block[idx].entry_num += SYS_USW_EXT_TCAM_SIZE;
            p_sys_league->lkup_level_count[idx] += SYS_USW_EXT_TCAM_SIZE;
            pb->entry_count += SYS_USW_EXT_TCAM_SIZE;
            pb->free_count += SYS_USW_EXT_TCAM_SIZE;
            pb->sub_entry_count[CTC_FPA_KEY_SIZE_640] += SYS_USW_EXT_TCAM_SIZE/8;
            pb->sub_free_count[CTC_FPA_KEY_SIZE_640] += SYS_USW_EXT_TCAM_SIZE/8;
            pb->sub_rsv_count[CTC_FPA_KEY_SIZE_640] = 0;
        }

        if(CTC_IS_BIT_SET(compress_blocks, idx) || CTC_IS_BIT_SET(expand_blocks, idx))
        {
            if(0 == pb->entry_count)
            {
                mem_free(pb->entries);
                continue;
            }
            p_entries = (ctc_fpa_entry_t**)mem_malloc(MEM_ACL_MODULE, pb->entry_count*sizeof(ctc_fpa_entry_t*));
            if(p_entries == NULL)
            {
                CTC_ERROR_RETURN(CTC_E_NO_MEMORY);
            }
            sal_memset(p_entries, 0, pb->entry_count*sizeof(ctc_fpa_entry_t*));
            sal_memcpy(p_entries, pb->entries, (tmp_size>pb->entry_count*sizeof(ctc_fpa_entry_t*)) ? (pb->entry_count*sizeof(ctc_fpa_entry_t*)):tmp_size);
            mem_free(pb->entries);
            pb->entries = p_entries;
        }
    }
    return CTC_E_NONE;
}
int32 _sys_usw_acl_adjust_ext_tcam(uint8 lchip, uint16 ext_tcam_bitmap)
{
    uint8 idx;
    uint8 field_step = FlowTcamTcamSizeCfg_ipeAcl1Cfg80BitsLkupEn_f-FlowTcamTcamSizeCfg_ipeAcl0Cfg80BitsLkupEn_f;
    FlowTcamTcamSizeCfg_m flow_tcam_cfg;
    uint32 cmd = DRV_IOR(FlowTcamTcamSizeCfg_t, DRV_ENTRY_FLAG);
    uint8 level_status[8] = {0};
    uint8 share_level_map[8] = {4,5,6,7,0,1,2,3};
    uint8 compress_blocks = 0;
    uint8 expand_blocks = 0;
    int32  ret = 0;
    sys_acl_league_t* p_tmp_league;

    CTC_ERROR_RETURN(_sys_usw_acl_get_ext_tcam_status(lchip, (uint8*)level_status));
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &flow_tcam_cfg));

    for(idx=0; idx < p_usw_acl_master[lchip]->igs_block_num; idx++)
    {
        if(!CTC_IS_BIT_SET(ext_tcam_bitmap, idx))
        {
            continue;
        }
        p_tmp_league = &(p_usw_acl_master[lchip]->league[idx]);
        if (p_tmp_league->lkup_level_bitmap != (1<<idx))
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"This block %u has been merged or be merged to others\n", idx);
            CTC_ERROR_GOTO(CTC_E_INVALID_PARAM, ret, error_end);
        }

        if(level_status[idx])
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR," This block %u has been expanded or the ext tcam used by scl\n", idx);
            CTC_ERROR_GOTO(CTC_E_INVALID_PARAM, ret, error_end);
        }

        if(CTC_IS_BIT_SET(ext_tcam_bitmap, share_level_map[idx]) || 3==level_status[share_level_map[idx]])
        {
            SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR," This block associated ext tcam have been used by other block or expand the shared one tcam\n");
            CTC_ERROR_GOTO(CTC_E_INVALID_PARAM, ret, error_end);
        }

        CTC_BIT_SET(expand_blocks, idx);
        SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg80BitsLkupEn_f+field_step*idx, &flow_tcam_cfg, 0);
        SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg160BitsLkupEn_f+field_step*idx, &flow_tcam_cfg, 0);
        SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg320BitsLkupEn_f+field_step*idx, &flow_tcam_cfg, 0);
        SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg640BitsLkupEn_f+field_step*idx, &flow_tcam_cfg, 0);

        SetFlowTcamTcamSizeCfg(V, share0Cfg80BitsLkupEn_f+field_step*(idx%4), &flow_tcam_cfg, 0);
        SetFlowTcamTcamSizeCfg(V, share0Cfg160BitsLkupEn_f+field_step*(idx%4), &flow_tcam_cfg, 0);
        SetFlowTcamTcamSizeCfg(V, share0Cfg320BitsLkupEn_f+field_step*(idx%4), &flow_tcam_cfg, 0);
        SetFlowTcamTcamSizeCfg(V, share0Cfg640BitsLkupEn_f+field_step*(idx%4), &flow_tcam_cfg, 0);

        if(level_status[share_level_map[idx]] > 0)
        {
            p_tmp_league = &(p_usw_acl_master[lchip]->league[share_level_map[idx]]);
            if (p_tmp_league->lkup_level_bitmap != (1<<share_level_map[idx]))
            {
                SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR,"The compressed block %u has been merged or be merged to others\n", share_level_map[idx]);
                CTC_ERROR_GOTO(CTC_E_INVALID_PARAM, ret, error_end);
            }
            CTC_BIT_SET(compress_blocks, share_level_map[idx]);
            SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg80BitsLkupEn_f+field_step*share_level_map[idx], &flow_tcam_cfg, 0);
            SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg160BitsLkupEn_f+field_step*share_level_map[idx], &flow_tcam_cfg, 0);
            SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg320BitsLkupEn_f+field_step*share_level_map[idx], &flow_tcam_cfg, 0);
            SetFlowTcamTcamSizeCfg(V, ipeAcl0Cfg640BitsLkupEn_f+field_step*share_level_map[idx], &flow_tcam_cfg, 0);
        }
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &flow_tcam_cfg), ret, error_end);

    }
    CTC_ERROR_GOTO(_sys_usw_acl_do_adjust_ext_tcam(lchip, expand_blocks, compress_blocks, (uint8*)level_status), ret, error_end);
    CTC_ERROR_GOTO(sys_usw_ftm_adjust_flow_tcam(lchip, expand_blocks, compress_blocks), ret, error_end);

error_end:
    cmd = DRV_IOW(FlowTcamTcamSizeCfg_t, DRV_ENTRY_FLAG);
    sal_memset(&flow_tcam_cfg, 0xFF, sizeof(flow_tcam_cfg));
    DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &flow_tcam_cfg);
    return ret;
}
int32 _sys_usw_acl_league_cancel_high_block(uint8 lchip, ctc_acl_league_t* league)
{
    uint8 block_id = 0;
    uint8 merge_to_block_id = 0;
    uint16 loop = 0;
    uint16 max_idx;
    uint16 bmp;
    uint16 move_cnt = 0;
    uint8  start_priority;
    uint16 new_entry_count;
    uint16 start_offset;
    sys_acl_league_t* p_sys_league = NULL;
    sys_acl_league_t* p_merged_league = NULL;
    sys_acl_league_t* p_cur_league = NULL;
    ctc_fpa_block_t*  p_merged_block;
    ctc_fpa_block_t*  p_cur_block;
    ctc_global_acl_property_t acl_property;
    ctc_acl_league_t tmp_league;
    sys_acl_entry_t* p_acl_entry;
    uint16 tmp_cnt;
    ctc_slistnode_t* group_node;
    ctc_slistnode_t* n_group_node;
    sys_acl_block_t* p_cur_acl_block;
    sys_acl_block_t* p_merged_acl_block;
    sys_acl_group_t* pg = NULL;
    sys_acl_fpa_ecnt_t fpa_ecnt;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (league->ext_tcam_bitmap)
    {
        return CTC_E_NOT_SUPPORT;
    }

    block_id = (CTC_INGRESS == league->dir ? league->acl_priority: league->acl_priority + ACL_IGS_BLOCK_MAX_NUM);
    p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
    p_cur_block = &p_usw_acl_master[lchip]->block[block_id].fpab;
    p_cur_league  = &(p_usw_acl_master[lchip]->league[block_id]);
    start_priority = p_cur_league->merged_to;

    merge_to_block_id = (CTC_INGRESS == league->dir ? p_cur_league->merged_to: p_cur_league->merged_to + ACL_IGS_BLOCK_MAX_NUM);
    p_merged_league = &p_usw_acl_master[lchip]->league[merge_to_block_id];
    p_merged_block = &p_usw_acl_master[lchip]->block[merge_to_block_id].fpab;

    /*  just for check lkup level bmp is valid or not.
        block status from 00111100  to 00001100
        00111100 ^ 00001100 = 00110000, only allowed the first N bit set to 1.
    */
    bmp = p_merged_league->lkup_level_bitmap ^ league->lkup_level_bitmap;
    tmp_cnt = (((1<<(league->acl_priority-start_priority)) - 1) << start_priority);
    if (tmp_cnt != bmp)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "bmp:0x%x, tmp_cnt:0x%x\n", bmp, tmp_cnt);
        return CTC_E_INVALID_PARAM;
    }

    /*check whether exist entry in the canceled block*/
    if(p_merged_block->entry_count != p_merged_block->free_count)
    {
        max_idx = p_merged_league->lkup_level_start[league->acl_priority];
        for(loop=0; loop < max_idx; loop++)
        {
            if(p_merged_block->entries[loop])
            {
                return CTC_E_IN_USE;
            }
        }
    }

    p_cur_acl_block = &p_usw_acl_master[lchip]->block[block_id];
    p_merged_acl_block = &p_usw_acl_master[lchip]->block[merge_to_block_id];
    if(NULL == p_cur_acl_block->group_list)
    {
        p_cur_acl_block->group_list = ctc_slist_new();
        if(NULL == p_cur_acl_block->group_list)
        {
            return CTC_E_NO_MEMORY;
        }
    }

    /*1. move the group which exist entry to the current block, the group which not exist entry stay on the merge block*/
    CTC_SLIST_LOOP_DEL(p_merged_acl_block->group_list, group_node, n_group_node)
    {
        pg = _ctc_container_of(group_node, sys_acl_group_t, head);
        if(pg->entry_list.count)
        {
            ctc_slist_delete_node(p_merged_acl_block->group_list, group_node);
            ctc_slist_add_tail(p_cur_acl_block->group_list, group_node);
        }
    }

    /*2. Update league info*/
    sal_memset(&acl_property, 0, sizeof(acl_property));
    acl_property.dir = league->dir;
    for(loop = start_priority; loop < league->acl_priority; loop++)
    {
        block_id = (CTC_INGRESS == league->dir ? loop: loop + ACL_IGS_BLOCK_MAX_NUM);
        p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
        p_sys_league->merged_to = start_priority;
        acl_property.lkup_level = loop;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &acl_property, 1));

        acl_property.random_log_pri = start_priority;
        CTC_ERROR_RETURN(sys_usw_set_glb_acl_property(lchip, &acl_property, 1));
        move_cnt += p_merged_league->lkup_level_count[loop];
    }

    loop = league->acl_priority;
    while(CTC_IS_BIT_SET(p_merged_league->lkup_level_bitmap, loop))
    {
        block_id = (CTC_INGRESS == league->dir ? loop: loop + ACL_IGS_BLOCK_MAX_NUM);
        p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
        p_sys_league->merged_to = league->acl_priority;

        p_cur_league->lkup_level_count[loop] = p_merged_league->lkup_level_count[loop];
        p_cur_league->lkup_level_start[loop] = p_merged_league->lkup_level_start[loop]-move_cnt;
        CTC_BIT_SET(p_cur_league->lkup_level_bitmap, loop);
        CTC_BIT_UNSET(p_merged_league->lkup_level_bitmap, loop);

        acl_property.lkup_level = loop;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &acl_property, 1));
        acl_property.random_log_pri = league->acl_priority;
        CTC_ERROR_RETURN(sys_usw_set_glb_acl_property(lchip, &acl_property, 1));
        loop++;
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "    move cnt:%u, merge start offset %u %u %u %u\n", move_cnt, \
        p_merged_block->start_offset[CTC_FPA_KEY_SIZE_80], p_merged_block->start_offset[CTC_FPA_KEY_SIZE_160],\
        p_merged_block->start_offset[CTC_FPA_KEY_SIZE_320],p_merged_block->start_offset[CTC_FPA_KEY_SIZE_640]);

    /*3. reset the current block*/
    if(move_cnt >= p_merged_block->start_offset[CTC_FPA_KEY_SIZE_640])
    {
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_640] = 0;
        tmp_cnt = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_640]-p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_640];
        p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] = (p_merged_block->entry_count-move_cnt)/8;
        p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_640] = p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] - tmp_cnt;
    }
    else if(move_cnt >= p_merged_block->start_offset[CTC_FPA_KEY_SIZE_320])
    {
        tmp_cnt = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_320]-p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_320];
        p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_320] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_320]-\
                                                                    (move_cnt-p_merged_block->start_offset[CTC_FPA_KEY_SIZE_320])/4;
        p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_320] = p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_320]-tmp_cnt;
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_320] = 0;
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_640] = p_merged_block->start_offset[CTC_FPA_KEY_SIZE_640] - move_cnt;
        p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_640];
        p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_640] = p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_640];
    }
    else if(move_cnt >= p_merged_block->start_offset[CTC_FPA_KEY_SIZE_160])
    {
        tmp_cnt = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_160]-p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_160];
        p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_160] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_160]-\
                                                                    (move_cnt-p_merged_block->start_offset[CTC_FPA_KEY_SIZE_160])/2;
        p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_160] = p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_160]-tmp_cnt;
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_160] = 0;
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_640] = p_merged_block->start_offset[CTC_FPA_KEY_SIZE_640] - move_cnt;
        p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_640];
        p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_640] = p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_640];
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_320] = p_merged_block->start_offset[CTC_FPA_KEY_SIZE_320] - move_cnt;
        p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_320] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_320];
        p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_320] = p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_320];
    }
    else
    {
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_80] = 0;
        tmp_cnt = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_80]-p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_80];
        p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_80] = p_merged_block->entry_count-move_cnt;
        p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_80] = p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_80] - tmp_cnt;
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_640] = p_merged_block->entry_count-move_cnt;
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_320] = p_merged_block->entry_count-move_cnt;
        p_cur_block->start_offset[CTC_FPA_KEY_SIZE_160] = p_merged_block->entry_count-move_cnt;
    }

    /*4. update the entry's offset*/
    new_entry_count = p_merged_block->entry_count-move_cnt;
    p_cur_block->entry_count = new_entry_count;
    p_cur_block->part_num = 1;
    block_id = (CTC_INGRESS == league->dir ? league->acl_priority: league->acl_priority + ACL_IGS_BLOCK_MAX_NUM);
    p_cur_block->free_count = p_merged_block->free_count -  move_cnt;
    MALLOC_ZERO(MEM_ACL_MODULE, p_cur_block->entries, sizeof(ctc_fpa_entry_t*)*new_entry_count);
    if(NULL == p_cur_block->entries)
    {
        return CTC_E_NO_MEMORY;
    }

    for(loop=0; loop < new_entry_count;loop++)
    {
        p_cur_block->entries[loop] = p_merged_block->entries[loop+move_cnt];
        if(p_cur_block->entries[loop])
        {
            p_acl_entry = _ctc_container_of(p_cur_block->entries[loop], sys_acl_entry_t, fpae);
            p_acl_entry->group->group_info.block_id = league->acl_priority;
            p_cur_block->entries[loop]->offset_a -= move_cnt;
            p_cur_block->entries[loop]->priority -= ((SYS_USW_ACL_UPA_EN(lchip, p_acl_entry->group->group_info.dir)) ? move_cnt : 0);
        }
    }
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_BLOCK, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_GROUP, 1);

    /*5. reset merged block*/
    mem_free(p_merged_block->entries);
    sal_memset(p_merged_block, 0, sizeof(ctc_fpa_block_t));
    MALLOC_ZERO(MEM_ACL_MODULE, p_merged_block->entries, sizeof(ctc_fpa_entry_t*)*move_cnt);
    if(NULL == p_merged_block->entries)
    {
        mem_free(p_cur_block->entries);
        return CTC_E_NO_MEMORY;
    }
    p_merged_block->part_num = 1;
    p_merged_block->entry_count = move_cnt;
    p_merged_block->free_count  = move_cnt;
    sys_usw_acl_split_fpa_block(lchip, move_cnt, fpa_ecnt);
    start_offset = 0;
    p_merged_block->start_offset[CTC_FPA_KEY_SIZE_160]    = 0;
    p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_160] = fpa_ecnt[CTC_FPA_KEY_SIZE_160]/2;
    p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_160]  = fpa_ecnt[CTC_FPA_KEY_SIZE_160]/2;
    p_merged_block->sub_rsv_count[CTC_FPA_KEY_SIZE_160]  = 0;
    start_offset += fpa_ecnt[CTC_FPA_KEY_SIZE_160];
    p_merged_block->start_offset[CTC_FPA_KEY_SIZE_320]    = start_offset;
    p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_320] = fpa_ecnt[CTC_FPA_KEY_SIZE_320]/4;
    p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_320]  = fpa_ecnt[CTC_FPA_KEY_SIZE_320]/4;
    p_merged_block->sub_rsv_count[CTC_FPA_KEY_SIZE_320]  = 0;
    start_offset += fpa_ecnt[CTC_FPA_KEY_SIZE_320];
    p_merged_block->start_offset[CTC_FPA_KEY_SIZE_640]    = start_offset;
    p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] = fpa_ecnt[CTC_FPA_KEY_SIZE_640]/8;
    p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_640]  = fpa_ecnt[CTC_FPA_KEY_SIZE_640]/8;
    p_merged_block->sub_rsv_count[CTC_FPA_KEY_SIZE_640]  = 0;

    /*6. Config hw table*/
    _sys_usw_acl_set_league_table(lchip, league);
    sal_memset(&tmp_league, 0, sizeof(tmp_league));
    tmp_league.dir = league->dir;
    tmp_league.acl_priority = start_priority;
    tmp_league.lkup_level_bitmap = p_merged_league->lkup_level_bitmap;
    _sys_usw_acl_set_league_table(lchip, &tmp_league);

    if(DRV_FROM_TMM(lchip) && league->dir == CTC_EGRESS)
    {
        uint32 cmd;
        EpeAclLkpSelectTcamSlice_m ds;
        cmd = DRV_IOR(EpeAclLkpSelectTcamSlice_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds);
        SetEpeAclLkpSelectTcamSlice(V, gAclLkpLevel_0_selectTcamSliceBitmap_f+start_priority, &ds, 1<<start_priority);
        SetEpeAclLkpSelectTcamSlice(V, gAclLkpLevel_0_selectTcamSliceBitmap_f+league->acl_priority, &ds, league->lkup_level_bitmap);
        cmd = DRV_IOW(EpeAclLkpSelectTcamSlice_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds);
    }
    return CTC_E_NONE;
}



int32
_sys_usw_acl_league_merge_high_block(uint8 lchip, ctc_acl_league_t* league, uint8 merged_priority)
{
    uint8 block_id = 0;
    uint8 merged_block_id = 0;
    uint8 exist_high = 0;
    uint16 loop = 0;
    uint16 bmp;
    uint16 tmp_bmp;
    uint16 move_cnt = 0;
    uint16 new_entry_count;
    sys_acl_league_t* p_sys_league = NULL;
    sys_acl_league_t* p_merged_league = NULL;
    sys_acl_league_t* p_cur_league = NULL;
    ctc_fpa_block_t*  p_merged_block;
    ctc_fpa_block_t*  p_cur_block;
    ctc_fpa_block_t*  p_block;
    ctc_global_acl_property_t acl_property;
    sys_acl_entry_t* p_acl_entry;
    ctc_fpa_entry_t** tmp_entries = NULL;
    uint32 cmd = 0;
    ds_t  ds;
    ctc_slistnode_t* group_node;
    ctc_slistnode_t* n_group_node;
    sys_acl_block_t* p_cur_acl_block;
    sys_acl_block_t* p_merged_acl_block;
    sys_acl_group_t* pg = NULL;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if (league->ext_tcam_bitmap)
    {
        return CTC_E_NOT_SUPPORT;
    }

    block_id = (CTC_INGRESS == league->dir ? league->acl_priority: league->acl_priority + ACL_IGS_BLOCK_MAX_NUM);
    p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
    p_cur_block = &p_usw_acl_master[lchip]->block[block_id].fpab;
    p_cur_league  = &(p_usw_acl_master[lchip]->league[block_id]);

    merged_block_id = (CTC_INGRESS == league->dir ? merged_priority: merged_priority + ACL_IGS_BLOCK_MAX_NUM);
    p_merged_league = &p_usw_acl_master[lchip]->league[merged_block_id];
    p_merged_block = &p_usw_acl_master[lchip]->block[merged_block_id].fpab;

    bmp = p_merged_league->lkup_level_bitmap ^ league->lkup_level_bitmap;
    tmp_bmp = 0xFFFF;
    tmp_bmp = ((uint16)(tmp_bmp >> merged_priority)) << merged_priority;
    if (bmp & tmp_bmp)
    {
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "  bmp:0x%x, tmp bmp:0x%x\n", bmp, tmp_bmp);
        return CTC_E_INVALID_PARAM;
    }

    if(p_cur_block->entry_count != p_cur_block->free_count)
    {
        exist_high = 1;
    }
    for(loop=league->acl_priority+1; loop < merged_priority; loop++)
    {
        block_id = (CTC_INGRESS == league->dir ? loop: loop + ACL_IGS_BLOCK_MAX_NUM);
        p_block = &p_usw_acl_master[lchip]->block[block_id].fpab;
        if(p_block->entry_count != p_block->free_count)
        {
            return CTC_E_IN_USE;
        }
    }

    if(p_merged_block->entry_count != p_merged_block->free_count && exist_high)
    {
        return CTC_E_IN_USE;
    }

    /*1. update league info*/
    block_id = (CTC_INGRESS == league->dir ? league->acl_priority: league->acl_priority + ACL_IGS_BLOCK_MAX_NUM);
    move_cnt = p_usw_acl_master[lchip]->block[block_id].entry_num;
    sal_memset(&acl_property, 0, sizeof(acl_property));
    acl_property.dir = league->dir;
    for(loop = league->acl_priority+1; loop < merged_priority; loop++)
    {
        block_id = (CTC_INGRESS == league->dir ? loop: loop + ACL_IGS_BLOCK_MAX_NUM);
        p_block = &p_usw_acl_master[lchip]->block[block_id].fpab;
        p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
        p_sys_league->merged_to = league->acl_priority;
        p_sys_league->lkup_level_bitmap = 0;

        CTC_BIT_SET(p_cur_league->lkup_level_bitmap, loop);
        p_cur_league->lkup_level_start[loop] = move_cnt;
        p_cur_league->lkup_level_count[loop] = p_usw_acl_master[lchip]->block[block_id].entry_num;
        acl_property.lkup_level = loop;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &acl_property, 1));
        acl_property.random_log_pri = league->acl_priority;
        CTC_ERROR_RETURN(sys_usw_set_glb_acl_property(lchip, &acl_property, 1));

        move_cnt += p_usw_acl_master[lchip]->block[block_id].entry_num;
        if(p_block->entries)
        {
            mem_free(p_block->entries);
        }
        sal_memset(p_block, 0, sizeof(ctc_fpa_block_t));
    }

    loop = merged_priority;
    while(CTC_IS_BIT_SET(p_merged_league->lkup_level_bitmap, loop))
    {
        block_id = (CTC_INGRESS == league->dir ? loop: loop + ACL_IGS_BLOCK_MAX_NUM);
        p_sys_league = &(p_usw_acl_master[lchip]->league[block_id]);
        p_sys_league->merged_to = league->acl_priority;

        p_cur_league->lkup_level_count[loop] = p_merged_league->lkup_level_count[loop];
        p_cur_league->lkup_level_start[loop] = p_merged_league->lkup_level_start[loop] + move_cnt;
        CTC_BIT_SET(p_cur_league->lkup_level_bitmap, loop);
        CTC_BIT_UNSET(p_merged_league->lkup_level_bitmap, loop);
        acl_property.lkup_level = loop;
        CTC_ERROR_RETURN(sys_usw_get_glb_acl_property(lchip, &acl_property, 1));
        acl_property.random_log_pri = league->acl_priority;
        CTC_ERROR_RETURN(sys_usw_set_glb_acl_property(lchip, &acl_property, 1));
        loop++;
    }

    /*2. reset current block*/
    new_entry_count = p_merged_block->entry_count+move_cnt;
    MALLOC_ZERO(MEM_ACL_MODULE, tmp_entries, sizeof(ctc_fpa_entry_t*)*new_entry_count);
    if(NULL == tmp_entries)
    {
        return CTC_E_NO_MEMORY;
    }

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "    move cnt:%u, new count:%u\n", move_cnt, new_entry_count);
    if(exist_high)
    {
        uint16 tmp_cnt = move_cnt - p_cur_block->entry_count;
        sal_memcpy(tmp_entries, p_cur_block->entries, sizeof(ctc_fpa_entry_t*)*p_cur_block->entry_count);
        mem_free(p_cur_block->entries);
        p_cur_block->entries = tmp_entries;
        p_cur_block->free_count = new_entry_count-(p_cur_block->entry_count-p_cur_block->free_count);
        p_cur_block->entry_count = new_entry_count;
        if(p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_80])
        {
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_80] = p_cur_block->entry_count;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_80] = p_cur_block->free_count;
            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_160] = new_entry_count;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_160] = 0;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_160] = 0;
            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_320] = new_entry_count;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_320] = 0;
            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_640] = new_entry_count;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
        }
        else
        {
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] += ((p_merged_block->entry_count+tmp_cnt)/8);
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_640] += ((p_merged_block->entry_count+tmp_cnt)/8);
        }
    }
    else
    {
        mem_free(p_cur_block->entries);
        sal_memset(p_cur_block, 0, sizeof(ctc_fpa_block_t));
        p_cur_block->part_num = 1;
        p_cur_block->entry_count = new_entry_count;
        block_id = (CTC_INGRESS == league->dir ? league->acl_priority: league->acl_priority + ACL_IGS_BLOCK_MAX_NUM);
        p_cur_block->free_count = p_merged_block->free_count + move_cnt;
        p_cur_block->entries = tmp_entries;
        for(loop=0; loop < p_merged_block->entry_count;loop++)
        {
            p_cur_block->entries[loop+move_cnt] = p_merged_block->entries[loop];
            if(p_cur_block->entries[loop+move_cnt])
            {
                p_acl_entry = _ctc_container_of(p_cur_block->entries[loop+move_cnt], sys_acl_entry_t, fpae);
                p_cur_block->entries[loop+move_cnt]->offset_a += move_cnt;
                p_cur_block->entries[loop+move_cnt]->priority += ((SYS_USW_ACL_UPA_EN(lchip, p_acl_entry->group->group_info.dir)) ? move_cnt : 0);
            }
        }

        if(p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_80])
        {
            uint16 tmp_cnt = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_80] - p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_80];
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_80] = p_merged_block->entry_count+move_cnt;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_80] = p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_80] - tmp_cnt;

            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_160] = new_entry_count;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_160] = 0;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_160] = 0;
            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_320] = new_entry_count;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_320] = 0;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_320] = 0;
            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_640] = new_entry_count;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] = 0;
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_640] = 0;
        }
        else
        {
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_160] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_160] + (move_cnt/2);
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_160] = p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_160] + (move_cnt/2);

            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_320] = p_merged_block->start_offset[CTC_FPA_KEY_SIZE_320] + move_cnt;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_320] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_320];
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_320] = p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_320];

            p_cur_block->start_offset[CTC_FPA_KEY_SIZE_640] = p_merged_block->start_offset[CTC_FPA_KEY_SIZE_640] + move_cnt;
            p_cur_block->sub_entry_count[CTC_FPA_KEY_SIZE_640] = p_merged_block->sub_entry_count[CTC_FPA_KEY_SIZE_640];
            p_cur_block->sub_free_count[CTC_FPA_KEY_SIZE_640] = p_merged_block->sub_free_count[CTC_FPA_KEY_SIZE_640];

        }
    }

    /*3. move all the group to the current block*/
    p_cur_acl_block = &p_usw_acl_master[lchip]->block[block_id];
    loop=league->acl_priority+1;
    while(CTC_IS_BIT_SET(league->lkup_level_bitmap, loop))
    {
        block_id = (CTC_INGRESS == league->dir ? loop: loop + ACL_IGS_BLOCK_MAX_NUM);
        p_merged_acl_block = &p_usw_acl_master[lchip]->block[block_id];
        CTC_SLIST_LOOP_DEL(p_merged_acl_block->group_list, group_node, n_group_node)
        {
            pg = _ctc_container_of(group_node, sys_acl_group_t, head);
            pg->group_info.block_id = league->acl_priority;
            ctc_slist_add_tail(p_cur_acl_block->group_list, group_node);
        }
        ctc_slist_free(p_merged_acl_block->group_list);
        p_merged_acl_block->group_list = NULL;
        loop++;
    }
    /*4. free merged block*/
    mem_free(p_merged_block->entries);
    sal_memset(p_merged_block, 0, sizeof(ctc_fpa_block_t));

    if (CTC_INGRESS == league->dir)
    {
        cmd = DRV_IOR(IpeAclQosCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds));
        SetIpeAclQosCtl(V, acl0AdMergeBitMap_f+merged_priority, &ds, 0);
        SetIpeAclQosCtl(V, acl0AdMergeBitMap_f+league->acl_priority, &ds, (league->lkup_level_bitmap >> (league->acl_priority+1)));
        cmd = DRV_IOW(IpeAclQosCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds));
    }
    else
    {
        cmd = DRV_IOR(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds));
        SetEpeAclQosCtl(V, acl0AdMergeBitMap_f+merged_priority, &ds, 0);
        SetEpeAclQosCtl(V, acl0AdMergeBitMap_f+league->acl_priority, &ds, (league->lkup_level_bitmap >> (league->acl_priority+1)));
        cmd = DRV_IOW(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds));

        if(DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(EpeAclLkpSelectTcamSlice_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds);
            SetEpeAclLkpSelectTcamSlice(V, gAclLkpLevel_0_selectTcamSliceBitmap_f+merged_priority, &ds, 1<<merged_priority);
            SetEpeAclLkpSelectTcamSlice(V, gAclLkpLevel_0_selectTcamSliceBitmap_f+league->acl_priority, &ds, league->lkup_level_bitmap);
            cmd = DRV_IOW(EpeAclLkpSelectTcamSlice_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, DRV_CMD_BMP_EN(cmd, MCHIP_FEATURE_PP_EN(lchip,CTC_FEATURE_ACL)), &ds);
        }
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_BLOCK, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_ACL, SYS_WB_APPID_ACL_SUBID_GROUP, 1);

    return CTC_E_NONE;
}



int32
sys_usw_acl_array_is_empty(uint8* array, uint32 len)
{
    uint32 loop = 0;
    do
    {
        if (array[loop++] != 0)
        {
            return FALSE;
        }
    }while(loop<len);
    return TRUE;
}

char *ifp_field_str[] = {
/*<IFP_FIELD_START>*/
"L2-TYPE",
"L3-TYPE",
"L3-EXT-TYPE",
"L4-TYPE",
"L4-USER-TYPE",
"MAC-SA",
"MAC-DA",
"STAG-VALID",
"PKT-STAG-VALID",
"PKT-CTAG-VALID",
"SVLAN-ID",
"STAG-COS",
"STAG-CFI",
"CTAG-VALID",
"CVLAN-ID",
"CTAG-COS",
"CTAG-CFI",
"SVLAN-RANGE",
"CVLAN-RANGE",
"ETHER-TYPE",
"VLAN-NUM",
"STP-STATE",
"MAPPED-STAG-VALID",
"MAPPED-SVLAN-ID",
"MAPPED-SVLAN-CFI",
"MAPPED-SVLAN-COS",
"MAPPED-CTAG-VALID",
"MAPPED-CVLAN-ID",
"MAPPED-CVLAN-CFI",
"MAPPED-CVLAN-COS",
"IP-SA",
"IP-DA",
"IPV6-SA",
"IPV6-DA",
"IPV6-FLOW-LABEL",
"IP-PROTOCOL",
"IP-DSCP",
"IP-PRECEDENCE",
"IP-ECN",
"IP-FRAG",
"IP-HDR-ERROR",
"IP-OPTIONS",
"IP-PKT-LEN-RANGE",
"IP-TTL",
"IS-IP-PKT",
"IP-IDENTIFICATION",
"IP-PKT-LEN",
"ARP-OP-CODE",
"ARP-PROTOCOL-TYPE",
"ARP-SENDER-IP",
"ARP-TARGET-IP",
"ARP-MAC-DA-CHK-FAIL",
"ARP-MAC-SA-CHK-FAIL",
"ARP-SENDERIP-CHK-FAIL",
"ARP-TARGETIP-CHK-FAIL",
"GARP",
"SENDER-MAC",
"TARGET-MAC",
"RARP",
"ARP-HARDWARE-TYPE",
"ARP-PROTOCOL-ADDLEN",
"ARP-HARDWARE-ADDLEN",
"IS-ARP-PKT",
"L4-DST-PORT",
"L4-SRC-PORT",
"L4-SRC-PORT-RANGE",
"L4-DST-PORT-RANGE",
"TCP-ECN",
"TCP-FLAGS",
"TCP-OPTIONS",
"GRE-KEY",
"GRE-FLAGS",
"GRE-PROTOCOL-TYPE",
"NVGRE-KEY",
"VN-ID",
"VXLAN-FLAGS",
"VXLAN-RSV1",
"VXLAN-RSV2",
"ICMP-CODE",
"ICMP-TYPE",
"IGMP-TYPE",
"LABEL-NUM",
"MPLS-LABEL0",
"MPLS-EXP0",
"MPLS-SBIT0",
"MPLS-TTL0",
"MPLS-LABEL1",
"MPLS-EXP1",
"MPLS-SBIT1",
"MPLS-TTL1",
"MPLS-LABEL2",
"MPLS-EXP2",
"MPLS-SBIT2",
"MPLS-TTL2",
"MPLS-LABEL3",
"MPLS-LABEL4",
"MPLS-LABEL5",
"MPLS-LABEL6",
"MPLS-LABEL7",
"INTERFACE-ID",
"RAL-EXIST",
"GAL-EXIST",
"CW-EXIST",
"IP-OVER-MPLS",
"IPV6-OVER-MPLS",
"MPLS-CW",
"MPLS-FWD-LABEL",
"MPLS-FWD-EXP",
"MPLS-FWD-SBIT",
"MPLS-FWD-TTL",
"NPM-IM-FLOW-ID",
"NPM-IM-L-FLAG",
"NPM-IM-D-FLAG",
"NSH-CBIT",
"NSH-OBIT",
"NSH-NEXT-PROTOCOL",
"NSH-SI",
"NSH-SPI",
"NSH-TERMINAL",
"IS-Y1731-OAM",
"ETHER-OAM-LEVEL",
"ETHER-OAM-OP-CODE",
"ETHER-OAM-VERSION",
"SLOW-PROTOCOL-CODE",
"SLOW-PROTOCOL-FLAGS",
"SLOW-PROTOCOL-SUB-TYPE",
"PTP-MESSAGE-TYPE",
"PTP-VERSION",
"FCOE-DST-FCID",
"FCOE-SRC-FCID",
"WLAN-RADIO-MAC",
"WLAN-RADIO-ID",
"WLAN-CTL-PKT",
"SATPDU-MEF-OUI",
"SATPDU-OUI-SUB-TYPE",
"SATPDU-PDU-BYTE",
"INGRESS-NICKNAME",
"EGRESS-NICKNAME",
"IS-ESADI",
"IS-TRILL-CHANNEL",
"TRILL-INNER-VLANID",
"TRILL-INNER-VLANID-VALID",
"TRILL-KEY-TYPE",
"TRILL-LENGTH",
"TRILL-MULTIHOP",
"TRILL-MULTICAST",
"TRILL-VERSION",
"TRILL-TTL",
"DOT1AE-UNKNOW-PKT",
"DOT1AE-ES",
"DOT1AE-SC",
"DOT1AE-AN",
"DOT1AE-SL",
"DOT1AE-PN",
"DOT1AE-SCI",
"DOT1AE-CBIT",
"DOT1AE-EBIT",
"DOT1AE-SCB",
"DOT1AE-VER",
"DOT1AE-SPI",
"INT-TYPE",
"INT-LEN",
"INT-VER",
"INT-EBIT",
"INT-MBIT",
"INT-HOP-ML",
"INT-REMAIN-HOP-CNT",
"INT-INSTRUCTION",
"UDF",
"SUDF",
"UDF-RANGE",
"UDF-AD-ID",
"SUDF-AD-ID",
"PORT",
"PORT-BITMAP",
"LPORT",
"CLASS-ID",
"LOGIC-SRC-PORT",
"LOGIC-DST-PORT",
"SRC-GPORT",
"DECAP",
"ENCAP",
"ELEPHANT-PKT",
"VXLAN-PKT",
"ROUTED-PKT",
"PKT-FWD-TYPE",
"MACSA-LKUP",
"MACSA-HIT",
"MACDA-LKUP",
"MACDA-HIT",
"IPSA-LKUP",
"IPSA-HIT",
"IPDA-LKUP",
"IPDA-HIT",
"L2-STATION-MOVE",
"MAC-SECURITY-DISCARD",
"DST-CID",
"SRC-CID",
"PORT-CID",
"VLAN-CID",
"L3IF-CID",
"SCL-CID",
"TUNNEL-CID",
"FLOW-CID",
"FID-CID",
"NEXTHOP-CID",
"DISCARD",
"CPU-REASON-ID",
"DST-GPORT",
"DST-NHID",
"MCAST-RPF-CHECK-FAIL",
"VRFID",
"METADATA",
"CUSTOMER-ID",
"IS-LOG-PKT",
"PRIORITY",
"COLOR",
"FID",
"MIRROR-PKT",
"ISOLATION-ID",
"LP-GRP",
"INNER-HEAD",
"IS-MY-SID",
"SNIFFING-PKT",
"MARK-ECN",
"CONGEST-EVENT",
"BURST-EVENT",
"NAT-IFTYPE",
"LDP-CID",
"APS-PROTECT1-EN",
"AWARE-TUNNEL-INFO",
"HASH-VALID",
"IS-ROUTER-MAC",
"INNER-IS-RTMAC",
"HASH-SEL-ID",
"STK-HDR-EXIST",
"STK-LKUP",
"STK-DST-GPORT",
"STK-SRC-GPORT",
"STK-FID",
"STK-LOGIC-SRC-PORT",
"STK-PRIORITY",
"STK-SRC-CID",
"STK-MIRROR-PKT",
"TO-STK",
"UDF-ENTRY-VALID",
"VLAN-XLATE-HIT",
"GEM-PORT",
"PRESEL-ENTRY-VALID",
"SRV6-SRH-FLAG",
"SRV6-SRH-NH",
"SRV6-SRH-RT",
"SRV6-SRH-SL",
"SRV6-SRH-LE",
"SRV6-SRH-TAG",
"SUDF-RANGE",
"IPFIX-PROFILE-ID",
"INT-PKT",
"XDATA",
"L4-HDR-ERROR",
"LEN-ERROR",
"ROUTE-DATA",
"BFD-MY-DISC",
"BFD-YOUR-DISC",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"LT-ID",
"LT-ID1",
"LT-ID2",
"LT-CLASS",
"DESTMAP",
"NH-OFFSET",
"NH-EXT",
"DEST-APS",
"DEST-ECMP",
"RANGE-CHECK",
"EXCEPTION-GID",
"EXCEPTION-FATAL-EXCP-ID",
"EXCEPTION-EXCP-EN",
"EXCEPTION-FATAL-EN",
"UDF1-PROF-ID",
"UDF1-VALID-BITMAP",
"UDF2-PROF-ID",
"UDF2-VALID-BITMAP",
"IS-NVGRE-PKT",
"GRE-WITH-KEY",
"L4-DP-SHARE",
"L4-SP-SHARE",
"VN-ID-SHARE",
"VXLAN-FLAGS-SHARE",
"Y1731-OAM-LEVEL",
"Y1731-OAM-OP-CODE",
"Y1731-OAM-VERSION",
"GPORT-SHARE",
"LOGIC-PORT-SHARE",
"PBM",
"PORT-BITMAP-MODE0",
"PORT-BITMAP-MODE1",
"PORT-BITMAP-MODE2",
"PORT-BITMAP-MODE3",
"UDF1-CHUNK0",
"UDF1-CHUNK1",
"UDF1-CHUNK2",
"UDF1-CHUNK3",
"UDF1-CHUNK4",
"UDF1-CHUNK5",
"UDF1-CHUNK6",
"UDF1-CHUNK7",
"UDF2-CHUNK0",
"UDF2-CHUNK1",
"UDF2-CHUNK2",
"UDF2-CHUNK3",
"UDF2-CHUNK4",
"UDF2-CHUNK5",
"UDF2-CHUNK6",
"UDF2-CHUNK7",
"FLEX-HASH-CHUNK0",
"FLEX-HASH-CHUNK1",
"FLEX-HASH-CHUNK2",
"FLEX-HASH-CHUNK3",
"FULL-ETHER-TYPE",
"IPV6-SA-CHUNK0",
"IPV6-SA-CHUNK1",
"IPV6-SA-CHUNK2",
"IPV6-SA-CHUNK3",
"IPV6-DA-CHUNK0",
"IPV6-DA-CHUNK1",
"IPV6-DA-CHUNK2",
"IPV6-DA-CHUNK3",
"NSH-CH-CHUNK0",
"NSH-CH-CHUNK1",
"NSH-CH-CHUNK2",
"NSH-CH-CHUNK3",
"VLAN-XLATE0-HIT",
"VLAN-XLATE1-HIT",
"SRH-COMMON-HDR",
"XDATA-DW0",
"XDATA-DW1",
"XDATA-W0",
"XDATA-W1",
"XDATA-W2",
"XDATA-W3",
"XDATA-B0",
"XDATA-B1",
"XDATA-B2",
"XDATA-B3",
"STK-XDATA-DW0",
"STK-XDATA-DW1",
"STK-XDATA-W0",
"STK-XDATA-W1",
"STK-XDATA-B0",
"STK-XDATA-B1",
"STK-XDATA-B2",
"STK-XDATA-B3",
"STK-HDR-BMP",
"XD-IM-FLOW-ID",
"XD-IM-L-FLAG",
"XD-IM-D-FLAG",
"XD-IM-SRC-D-FLAG",
"IPV6-IM-FLOW-ID",
"IPV6-IM-L-FLAG",
"IPV6-IM-D-FLAG",
"INT-TYPE",
"INT-VER",
"INT-HOP-ML",
"INT-REMAIN-HOP-CNT",
"INT-INSTRUCTION",
"IS-FRAG",
/*<IFP_FIELD_END>*/
};


const char *key_type_str[CTC_ACL_KEY_FLEX_BASE] = {
"MAC_KEY",
"IPV4_KEY",
"MPLS_KEY",
"IPV6_KEY",
"HASH_MAC_KEY",
"HASH_IPV4_KEY",
"HASH_L2_L3_KEY",
"HASH_MPLS_KEY",
"HASH_IPV6_KEY",
"HASH_NSH_KEY",
"PBR_IPV4_KEY",
"PBR_IPV6_KEY",
"IPV4_EXT_KEY",
"MAC_IPV4_KEY",
"MAC_IPV4_EXT_KEY",
"IPV6_EXT_KEY",
"MAC_IPV6_KEY",
"CID_KEY",
"INTERFACE_KEY",
"FWD_KEY",
"FWD_EXT_KEY",
"COPP_KEY",
"COPP_EXT_KEY",
"UDF_KEY",
"STK_HDR_KEY"
};

uint32
sys_usw_acl_get_field_id(char* in)
{
    uint32 i = 0;
    for (i = 0; i < SYS_ACL_FIELD_COUNT; i++)
    {
        if (0 == sal_strcasecmp(in, ifp_field_str[i]))
        {
            return i;
        }
    }

    return 0xFFFFFFFF;
}

int32
_sys_usw_acl_get_flex_key_fields(uint8 lchip, ctc_acl_flex_key_t* acl_flex_key)
{
    sys_acl_fixed_key_t *p_fixed_key = NULL;

    if(SYS_ACL_KEY_IS_FLEX(acl_flex_key->key_type))
    {
        p_fixed_key = ctc_vector_get(p_usw_acl_master[lchip]->fixed_key_vec, acl_flex_key->key_type);
        if (NULL == p_fixed_key)
        {
            CTC_ERROR_RETURN(CTC_E_ENTRY_NOT_EXIST);
        }
        sal_memcpy(acl_flex_key->kset.w, p_fixed_key->kset.w, CTC_B2W_SIZE(CTC_FIELD_KEY_NUM) * 4);
    }
    else
    {
        if(p_usw_acl_master[lchip]->kset_db[acl_flex_key->key_type] != NULL)
        {
            sal_memcpy(acl_flex_key->kset.w, p_usw_acl_master[lchip]->kset_db[acl_flex_key->key_type], CTC_B2W_SIZE(CTC_FIELD_KEY_NUM) * 4);
        }
        else
        {
            return CTC_E_NOT_SUPPORT;
        }
    }
    return CTC_E_NONE;
}

void
_sys_usw_acl_show_kset(uint8 lchip, ctc_acl_flex_key_t * acl_flex_key)
{
    uint16 loop = 0;

    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8s  %-24s\n", "ID", "FIELD");
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------------------\n");
    for (loop = 0; loop < CTC_FIELD_KEY_NUM; loop++)
    {
        if (!CTC_BMP_ISSET(acl_flex_key->kset.w, loop))
        {
            continue;
        }
        SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-8d  %-24s\n", loop, ifp_field_str[loop]);
    }
    SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    //SYS_ACL_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-16s: %s\n", "origin key type", key_type_str[acl_flex_key->origin_key_type]);
}

int32
sys_usw_acl_buffer_malloc(uint8 lchip, sys_acl_entry_t* pe, uint8 is_malloc)
{
    sys_acl_buffer_t* new_buffer = NULL;
    void* temp_action = NULL;

    if (!is_malloc)  /*free*/
    {
        if (!pe->ua)
        {
            return CTC_E_NONE;
        }
        if (!pe->ua_type)   /*buffer*/
        {
            temp_action = pe->ua->buffer.pa;

            mem_free(pe->ua);
            pe->ua = temp_action;   /*free buffer, ua point to action_data*/
            pe->ua_type = temp_action ? 1 : 0;
        }
        return CTC_E_NONE;
    }
    /*malloc*/
    if ((!pe->ua) ^ (!pe->ua_type) && !(pe->ad_type != SYS_ACL_AD_TYPE_DISABLE && (!pe->ua) && (pe->ua_type)))  /*buffer malloced, or action never malloced*/
    {
        return CTC_E_NONE;
    }
    if (!pe->ua_type)   /*buffer*/
    {
        pe->ua = mem_malloc(MEM_ACL_MODULE, sizeof(sys_acl_buffer_t));
        if (!pe->ua)
        {
            return CTC_E_NO_MEMORY;
        }
        sal_memset(pe->ua, 0, sizeof(sys_acl_buffer_t));
    }
    else    /*ad*/
    {
        new_buffer = mem_malloc(MEM_ACL_MODULE, sizeof(sys_acl_buffer_t));
        if (!new_buffer)
        {
            return CTC_E_NO_MEMORY;
        }
        sal_memset(new_buffer, 0, sizeof(sys_acl_buffer_t));
        if (SYS_ACL_ACTION_HASH_INGRESS == pe->action_type && pe->ua)
        {
            sal_memcpy(&new_buffer->ad, pe->ua, CTC_OFFSET_OF(sys_acl_hash_action_t,calc_key_len));
        }
        else if(pe->ua)
        {
            sal_memcpy(&new_buffer->ad, pe->ua, sizeof(sys_acl_tcam_action_t));
        }
        new_buffer->pa = (void*)pe->ua;
        pe->ua = (void*)new_buffer;
        pe->ua_type = 0;
    }
    return CTC_E_NONE;
}

void
sys_usw_acl_show_kset(uint8 lchip, ctc_acl_flex_key_t *acl_flex_key)
{
    if (!DRV_FROM_TMM(lchip) ||
        ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && acl_flex_key->dir == CTC_EGRESS) ||
        CTC_FLAG_ISSET(acl_flex_key->flag, CTC_ACL_FLEX_KEY_FLAG_HASH))
    {
        _sys_usw_acl_show_kset(lchip, acl_flex_key);
    }
    else
    {
        MCHIP_ACL(lchip)->show_kset(lchip, acl_flex_key);
    }
}

void*
sys_usw_acl_get_ldp_entry_by_eid(uint8 lchip, uint32 eid)
{
    sys_acl_ldp_entry_t ldp_entry;
    ldp_entry.entry_id = eid;
    return ctc_hash_lookup(p_usw_acl_master[lchip]->ldp_entry, (void*)&ldp_entry);
}
